I find it difficult to understand what happens when I try to insert descriptors / decorators. I am using python 2.7.
For example, suppose the following simplified versions propertyand classmethod:
class MyProperty(object):
def __init__(self, fget):
self.fget = fget
def __get__(self, obj, objtype=None):
print 'IN MyProperty.__get__'
return self.fget(obj)
class MyClassMethod(object):
def __init__(self, f):
self.f = f
def __get__(self, obj, objtype=None):
print 'IN MyClassMethod.__get__'
def f(*args, **kwargs):
return self.f(objtype, *args, **kwargs)
return f
Attempt to invest them:
class A(object):
@MyProperty
@MyClassMethod
def klsproperty(cls):
return 555
@MyProperty
def prop(self):
return 111
@MyClassMethod
def klsmethod(cls, x):
return x**2
% print A.klsproperty
IN MyProperty.__get__
...
TypeError: 'MyClassMethod' object is not callable
The __get__internal descriptor method is MyClassMethodnot called. If you don’t understand why, I tried using (no-op descriptor):
class NoopDescriptor(object):
def __init__(self, f):
self.f = f
def __get__(self, obj, objtype=None):
print 'IN NoopDescriptor.__get__'
return self.f.__get__(obj, objtype=objtype)
Attempt to use the descriptor / decorator no-op when nesting:
class B(object):
@NoopDescriptor
@MyProperty
def prop1(self):
return 888
@MyProperty
@NoopDescriptor
def prop2(self):
return 999
% print B().prop1
IN NoopDescriptor.__get__
IN MyProperty.__get__
888
% print B().prop2
IN MyProperty.__get__
...
TypeError: 'NoopDescriptor' object is not callable
I do not understand why it B().prop1works, but B().prop2does not work.
Questions:
- What am I doing wrong? Why am I getting an error
object is not callable? - Which is the right way? such that the best way to determine
MyClassPropertywhen reusing MyClassMethodand MyProperty(or classmethodand property)