`property`类型的__slots__

时间:2016-02-04 13:03:52

标签: python python-2.7 properties python-internals

那么与python property类型的交易是什么?它没有__slots____dict__。但__dict__类型的property显示了广告位参考。

In [28]: p = property(lambda: 5)

In [29]: hasattr(p, '__slots__')
Out[29]: False

In [30]: hasattr(p, '__dict__')
Out[30]: False

In [31]: type(p).__dict__
Out[31]: 
<dictproxy {'__delete__': <slot wrapper '__delete__' of 'property' objects>,
 '__doc__': <member '__doc__' of 'property' objects>,
 '__get__': <slot wrapper '__get__' of 'property' objects>,
 '__getattribute__': <slot wrapper '__getattribute__' of 'property' objects>,
 '__init__': <slot wrapper '__init__' of 'property' objects>,
 '__new__': <function __new__>,
 '__set__': <slot wrapper '__set__' of 'property' objects>,
 'deleter': <method 'deleter' of 'property' objects>,
 'fdel': <member 'fdel' of 'property' objects>,
 'fget': <member 'fget' of 'property' objects>,
 'fset': <member 'fset' of 'property' objects>,
 'getter': <method 'getter' of 'property' objects>,
 'setter': <method 'setter' of 'property' objects>}>

此外,我已尝试从属性继承以添加其他属性,但显而易见的方法搞砸了。

In [37]: property_ = type('property_', (property, ), dict(__slots__=('prop', )))

In [38]: p_ = property_(lambda: 5)
---------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-38-06c5a90565ef> in <module>()
----> 1 p_ = property_(lambda: 5)

AttributeError: 'property_' object attribute '__doc__' is read-only

如果property未实现__slots__功能,为什么我无法将属性分配给property个实例?

In [45]: p = property(lambda: 'prop')

In [46]: p.attr = 'attr'
--------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-46-71284e3de202> in <module>()
----> 1 p.attr = 'attr'

AttributeError: 'property' object has no attribute 'attr'

1 个答案:

答案 0 :(得分:2)

__slots__机制将C类型的已使用的功能公开给Python类型。 slot上名称中包含property的对象并不意味着它使用__slots__功能。它们只是使用C类型功能的对象。

property对象可以在不使用__slots__的情况下进行子类化:

>>> class Foo(property):
...     prop = 'bar'
...
>>> def test(self): return 'success'
...
>>> Foo(test).__get__(object())
'success'
>>> Foo(test).prop
'bar'

子类化为该子类的实例添加__dict__。或者,您只需实施descriptor protocol即可轻松创建相同的功能。