Path: csiph.com!v102.xanadu-bbs.net!xanadu-bbs.net!feeder.erje.net!eu.feeder.erje.net!newsfeed.xs4all.nl!newsfeed3a.news.xs4all.nl!xs4all!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.003 X-Spam-Evidence: '*H*': 0.99; '*S*': 0.00; 'python,': 0.02; '(except': 0.07; 'arguments': 0.09; 'arguments,': 0.09; 'subject:method': 0.09; 'python': 0.11; 'def': 0.12; 'thread': 0.14; ':-p': 0.16; 'bases,': 0.16; 'descriptor': 0.16; 'fancy': 0.16; 'metaclass': 0.16; 'optional': 0.16; 'parentheses': 0.16; 'wrote:': 0.18; 'not,': 0.20; 'import': 0.22; 'aug': 0.22; 'coding': 0.22; 'decorators': 0.24; 'replace': 0.24; 'pass': 0.26; 'required.': 0.27; 'header:In-Reply-To:1': 0.27; 'function': 0.29; 'wondering': 0.29; "doesn't": 0.30; 'message-id:@mail.gmail.com': 0.30; 'skip:( 20': 0.30; "i'm": 0.30; 'consequence': 0.31; 'inspect': 0.31; 'project?': 0.31; 'anyone': 0.31; 'class': 0.32; 'not.': 0.33; 'skip:_ 10': 0.34; 'something': 0.35; 'but': 0.35; 'received:google.com': 0.35; 'really': 0.36; 'acceptable': 0.36; 'returning': 0.36; 'method': 0.36; 'subject:?': 0.36; 'similar': 0.36; 'christian': 0.38; 'to:addr:python-list': 0.38; 'pm,': 0.38; 'does': 0.39; 'to:addr:python.org': 0.39; 'either': 0.39; 'called': 0.40; 'above,': 0.60; 'real': 0.63; 'skip:n 10': 0.64; 'provide': 0.64; 'realized': 0.68; 'helping': 0.70; 'subject:Making': 0.84 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :content-type; bh=IpNmz5atI7whPaCtEr6OdR6DMnRtBsa3McWvXohJoSM=; b=hgRAq99xQYIdDmRY79UUUtrJcPxPCe7v+Ft9xvfz7I0/og2tGcrhxXT8WzyH6MlBe8 mQjIQcWRg+MiikXiViRhVc2W+FpVC3OSxdBaPBP196S6Krc52tNkKbKkCfWEsC9IV9wk PC0QtfwhrOM+UAviLSaQFTRrQMASfjTNJ/aAAcNFaz8iGZP75UBpqbOVhW/41VR9Q5R6 pJuC7+Aw8pLxBciYkMZu8pqgO5muuKxhgtL5EQ13IZY8kZvTgeCzABLMaeuul2O98OfN J919hHKRdoxDOBfqqVcOm+SyM3JA6x2U/yHpQJ/dqRJVqiLYLPLigr3P8VlgqGfl1kue d29g== X-Received: by 10.70.108.164 with SMTP id hl4mr7341158pdb.70.1407275654414; Tue, 05 Aug 2014 14:54:14 -0700 (PDT) MIME-Version: 1.0 In-Reply-To: References: From: Ian Kelly Date: Tue, 5 Aug 2014 15:53:34 -0600 Subject: Re: Making every no-arg method a property? To: Python Content-Type: text/plain; charset=UTF-8 X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 41 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1407275663 news.xs4all.nl 2861 [2001:888:2000:d::a6]:60387 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:75761 On Tue, Aug 5, 2014 at 1:39 PM, Christian Calderon wrote: > I have been using python for 4 years now, and I just started learning ruby. > I like that in ruby I don't have to type parenthesis at the end of each > function call if I don't need to provide extra arguments. I just realized > right now that I can do something similar in python, if I make all methods > with only the implicitly passed 'self' into properties. Which means I can > either do some fancy coding and make a metaclass that does this > auto-magically, or I have to have property decorators all over the place :-P > . I was wondering what other thought of this, is it an overly fanciful way > of coding python, or is it an acceptable thing to do in a real project? > Also, would anyone be interested in helping me make this metaclass? The metaclass to do this is easy: import inspect import types class autoprop(type): def __init__(cls, name, bases, attrs): for name, value in attrs.items(): if (name.startswith('__') and name.endswith('__') or not isinstance(value, types.FunctionType)): continue argspec = inspect.getfullargspec(value) if (len(argspec.args) == 1 and not any([argspec.varargs, argspec.varkw, argspec.kwonlyargs])): setattr(cls, name, property(value)) But I'm in agreement with the others in this thread that it's not really a good idea. In addition to the arguments made by others, note that this doesn't actually make the parentheses optional; it makes their absence required. That's a fundamental limitation, because it's up to the descriptor to automatically call the method or not, and the descriptor has no way of knowing whether the thing it's returning is about to be called or not. Also, as a consequence of the above, note that this only works for methods that take no arguments at all (except self). If the method has optional arguments, and you replace it with a property, then you no longer have any way to pass those optional arguments.