property
对象是描述符。描述符仅在绑定到类时才具有特殊能力。否则,它们的行为与任何其他类完全相同。当您将属性放在列表中时,它不会绑定到类,因此它会丢失它的特殊属性。
例如,让我们看一个property
用纯 python 编写的描述符的实现:
class Property(object):
"Emulate PyProperty_Type() in Objects/descrobject.c"
def __init__(self, fget=None, fset=None, fdel=None, doc=None):
self.fget = fget
self.fset = fset
self.fdel = fdel
self.__doc__ = doc
def __get__(self, obj, objtype=None):
if obj is None:
return self
if self.fget is None:
raise AttributeError, "unreadable attribute"
return self.fget(obj)
def __set__(self, obj, value):
if self.fset is None:
raise AttributeError, "can't set attribute"
self.fset(obj, value)
def __delete__(self, obj):
if self.fdel is None:
raise AttributeError, "can't delete attribute"
self.fdel(obj)
注意__get__
,__set__
和的第二个参数__delete__
是 obj 吗? obj
是描述符绑定到的类的实例(它被传递给方法,self
好像这有助于澄清事情)。为了使整个 shebang 工作,描述符必须绑定到一个类,以便__get__
可以调用并obj
传递给它。如果描述符没有绑定到一个类,那么__get__
就不会被调用,并且您的描述符类将成为另一个类,其中包含一些永远不会被调用的魔术方法(除非您显式调用它们)。
也许更具体地说,当你这样做时:
a = instance.my_descriptor
这调用my_descriptor.__get__(instance)
并相应地:
instance.my_descriptor = a
来电my_descriptor.__set__(instance,a)
However, if my_descriptor
isn't bound to a class, then it behaves just like any other class (object) which explains what you're seeing.