bav*_*aza 7 python setattr slots python-internals
假设我有一个定义的类__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
Run Code Online (Sandbox Code Playgroud)
我可以定义__setattr__()吗?
既然Foo没有__dict__,它会更新什么?
Mar*_*ers 12
除了否定值之外,你的所有代码都会调用父类__setattr__,这正是没有你的__setattr__方法会发生的事情.所以简短的回答是:当然你可以定义一个__setattr__.
什么,你不能做的是重新__setattr__使用self.__dict__,因为槽类的实例不会有一个__dict__属性.但是这样的实例确实有一个self.x属性,它的内容只是没有存储在实例的字典中.
相反,槽值存储在__dict__实例字典将以其他方式存储的相同位置; 在对象堆上.空间保留用于len(__slots__)引用,类上的描述符代表您访问这些引用.
因此,在__setattr__钩子中,您可以直接调用这些描述符:
def __setattr__(self, key, value):
if key == 'x':
Foo.__dict__[key].__set__(self, -value)
Run Code Online (Sandbox Code Playgroud)
有趣的弯路:是的,在类没有__slots__属性,还有就是,这将使你的访问的描述符__dict__实例的对象:
>>> class Bar(object): pass
...
>>> Bar.__dict__['__dict__']
<attribute '__dict__' of 'Bar' objects>
>>> Bar.__dict__['__dict__'].__get__(Bar(), Bar)
{}
Run Code Online (Sandbox Code Playgroud)
这是正常实例可以查找的方式self.__dict__.这让你想知道Bar.__dict__对象的位置.在Python中,它一直是乌龟,你当然会在对象上看到这个对象type:
>>> 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})
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1393 次 |
| 最近记录: |