可以在具有__slots__的类中定义__setattr __()吗? [英] Can __setattr__() can be defined in a class with __slots__?

查看:114
本文介绍了可以在具有__slots__的类中定义__setattr __()吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说我有一个定义__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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆