`属性` 类型的 __slots__
__slots__ of `property` type
那么 python property
类型是怎么回事?它没有 __slots__
或 __dict__
。但是 property
类型的 __dict__
显示插槽引用。
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'
__slots__
机制向 Python 类型公开了一个 C 类型已经使用的特性。 property
上名称中带有 slot
的对象并不意味着它使用 __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.
轻松创建相同的功能
那么 python property
类型是怎么回事?它没有 __slots__
或 __dict__
。但是 property
类型的 __dict__
显示插槽引用。
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'
__slots__
机制向 Python 类型公开了一个 C 类型已经使用的特性。 property
上名称中带有 slot
的对象并不意味着它使用 __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.