Tanımlayıcıları/dekoratörleri yerleştirmeye çalıştığımda neler olduğunu anlamakta zorlanıyorum. Python 2.7 kullanıyorum.Python'da yuvalama tanımlayıcıları/dekoratörler
Örneğin, property
ve classmethod
aşağıdaki basitleştirilmiş versiyonları alalım:
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
yuvamýza çalışılıyor:
class A(object):
# doesn't work:
@MyProperty
@MyClassMethod
def klsproperty(cls):
return 555
# works:
@MyProperty
def prop(self):
return 111
# works:
@MyClassMethod
def klsmethod(cls, x):
return x**2
% print A.klsproperty
IN MyProperty.__get__
...
TypeError: 'MyClassMethod' object is not callable
iç tanımlayıcısı MyClassMethod
ait __get__
yöntemi denir almıyor.
class B(object):
# works:
@NoopDescriptor
@MyProperty
def prop1(self):
return 888
# doesn't work:
@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
: yuvalama hiçbir-op açıklayıcısı/dekoratör kullanmaya çalışıyor
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)
: (Ben düşündüğüm şey) bir no-op tanımlayıcısı atarak denedi neden anlamaya başarısız Neden B().prop1
çalışır ve B().prop2
neden anlamıyorum.
Sorular: Yanlış yapıyorum
- ? Neden
object is not callable
hatası alıyorum? - Doğru olan nedir? Örneğin. dekoratörler dekoratör o olarak onun süsleyen fonksiyonu ile çağrılır, parametreler olmadan kullanıldığında
MyClassMethod
veMyProperty
(veyaclassmethod
veproperty
) Bu durumda
Sezgisel olarak bunu anlamanın anahtarı, "MyProperty" öğesinin bir _data_ özniteliği gibi çalışan bir yöntem oluşturmasıdır, bu nedenle bir yöntem tanımlayıcısıyla onu yuvalayamazsınız. Bu sezgisel anlayış sadece sizi şimdiye kadar götürür; Tam hikaye isedev'in cevabında. – abarnert