Making every no-arg method a property?

Ian Kelly ian.g.kelly at gmail.com
Tue Aug 5 17:53:34 EDT 2014


On Tue, Aug 5, 2014 at 1:39 PM, Christian Calderon
<calderon.christian760 at gmail.com> 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.



More information about the Python-list mailing list