Python属性如何工作?

我已经成功地使用Python的属性,但我不明白他们如何工作。 如果我在一个类的外部解引用属性,我只是得到一个属性types的对象:

 @property def hello(): return "Hello, world!" hello # <property object at 0x9870a8> 

但是,如果我把一个财产放在一个class里,那么行为是非常不同的:

 class Foo(object): @property def hello(self): return "Hello, world!" Foo().hello # 'Hello, world!' 

我注意到,未绑定的Foo.hello仍然是property对象,所以类的实例化必须做到这一点,但是什么魔术?

正如其他人所指出的,他们使用了一种名为描述符的语言function。

当你通过类Foo.hello访问实际属性对象时,返回的原因在于属性如何实现__get__(self, instance, owner)特殊方法。 如果在实例上访问描述符,那么该实例将作为适当的parameter passing,而owner则是该实例的

另一方面,如果通过类访问它,那么instance是None,只有owner被传递。 property对象识别这个并返回self


除了描述符howto之外 ,还请参阅语言指南中的实现描述符和调用描述符的文档。

为了使@properties正常工作,该类需要成为对象的一个子类。 当类不是对象的子类时,那么当你第一次尝试访问setter时,它实际上会创build一个名字较短的新属性,而不是通过setter访问。

以下不能正常工作。

 class C(): # <-- Notice that object is missing def __init__(self): self._x = None @property def x(self): print 'getting value of x' return self._x @x.setter def x(self, x): print 'setting value of x' self._x = x >>> c = C() >>> cx = 1 >>> print cx, c._x 1 0 

以下将正常工作

 class C(object): def __init__(self): self._x = None @property def x(self): print 'getting value of x' return self._x @x.setter def x(self, x): print 'setting value of x' self._x = x >>> c = C() >>> cx = 1 setting value of x >>> print cx, c._x getting value of x 1 1 

属性是描述符 ,描述符在类实例的成员中特别performance。 简而言之,如果aAtypes的实例,而A.foo是描述符,则a.foo等同于A.foo.__get__(a)

property对象只是实现描述符协议: http : //docs.python.org/howto/descriptor.html