可以在具有__slots__的类中定义__setattr __()吗? [英] Can __setattr__() can be defined in a class with __slots__?
问题描述
说我有一个定义__slots__
的类:
class Foo(object):
__slots__ = ['x']
def __init__(self, x=1):
self.x = x
# will the following work?
def __setattr__(self, key, value):
if key == 'x':
object.__setattr__(self, name, -value) # Haha - let's set to minus x
我可以为此定义__setattr__()
吗?
由于Foo
没有__dict__
,它将更新什么?
Since Foo
has no __dict__
, what will it update?
推荐答案
您的所有代码(除取值之外)都调用了父类__setattr__
,这正是不使用__setattr__
方法会发生的情况.因此,简短的答案是:确保可以定义__setattr__
.
All your code does, apart from negate the value, is call the parent class __setattr__
, which is exactly what would happen without your __setattr__
method. So the short answer is: Sure you can define a __setattr__
.
您不能做的是重新定义__setattr__
以使用self.__dict__
,因为具有插槽的类的实例没有具有一个__dict__
属性.但是这类实例 do 具有self.x
属性,它的内容只是不存储在该实例的字典中.
What you cannot do is redefine __setattr__
to use self.__dict__
, because instances of a class with slots do not have a __dict__
attribute. But such instances do have a self.x
attribute, it's contents are just not stored in a dictionary on the instance.
相反,插槽值存储在相同的位置,否则将存储__dict__
实例字典.在对象堆上.为len(__slots__)
引用保留了空间,并且类上的描述符访问这些代表您的参考.
Instead, slot values are stored in the same location a __dict__
instance dictionary would otherwise be stored; on the object heap. Space is reserved for len(__slots__)
references, and descriptors on the class access these references on your behalf.
因此,在__setattr__
挂钩中,您可以直接直接调用这些描述符:
So, in a __setattr__
hook, you can just call those descriptors directly instead:
def __setattr__(self, key, value):
if key == 'x':
Foo.__dict__[key].__set__(self, -value)
有趣的绕道:是的,在没有__slots__
属性的类上,存在 一个描述符,该描述符可让您访问实例的__dict__
对象:
Interesting detour: yes, on classes without a __slots__
attribute, there is a descriptor that would give you access to the __dict__
object of instances:
>>> class Bar(object): pass
...
>>> Bar.__dict__['__dict__']
<attribute '__dict__' of 'Bar' objects>
>>> Bar.__dict__['__dict__'].__get__(Bar(), Bar)
{}
这是 normal 实例查找self.__dict__
的方式.这使您想知道在哪里找到Bar.__dict__
对象.在Python中,它是一直向下滚动,您会发现该对象放在type
对象上
which is how normal instances can look up self.__dict__
. Which makes you wonder where the Bar.__dict__
object is found. In Python, it is turtles all the way down, you'd look that object up on the type
object of course:
>>> type.__dict__['__dict__']
<attribute '__dict__' of 'type' objects>
>>> type.__dict__['__dict__'].__get__(Bar, type)
dict_proxy({'__dict__': <attribute '__dict__' of 'Bar' objects>, '__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'Bar' objects>, '__doc__': None})
这篇关于可以在具有__slots__的类中定义__setattr __()吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!