Python属性如何工作?

时间:2011-05-31 21:06:36

标签: python properties

我已成功使用Python属性,但我看不出它们是如何工作的。如果我取消引用类之外的属性,我只会获得类型为property的对象:

@property
def hello(): return "Hello, world!"

hello  # <property object at 0x9870a8>

但是如果我在一个类中放置一个属性,行为就会大不相同了:

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

Foo().hello # 'Hello, world!'

我注意到,未绑定的Foo.hello仍然是property对象,因此类实例化必须具有魔力,但这有什么神奇之处?

4 个答案:

答案 0 :(得分:46)

正如其他人所说,他们使用一种称为描述符的语言功能。

通过类Foo.hello访问实际属性对象时返回的原因在于属性如何实现__get__(self, instance, owner)特殊方法:

  • 如果在实例上访问描述符,则该实例作为适当的参数传递,owner是该实例的。 / LI>
  • 通过课程访问时,instance为无,仅传递ownerproperty对象识别此内容并返回self

除了Descriptors howto之外,另请参阅语言指南中有关Implementing DescriptorsInvoking Descriptors的文档。

答案 1 :(得分:21)

为了使@properties正常工作,该类必须是 object 的子类。 当类不是对象的子类时,那么当您第一次尝试访问setter时,它实际上会创建一个名称较短的新属性,而不是通过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()
>>> c.x = 1
>>> print c.x, 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()
>>> c.x = 1
setting value of x
>>> print c.x, c._x
getting value of x
1 1

答案 2 :(得分:11)

属性为descriptors,描述符在类实例的成员时特别表现。简而言之,如果aA类型的实例,而A.foo是描述符,则a.foo相当于A.foo.__get__(a)

答案 3 :(得分:3)

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