简体   繁体   English

当 __dict__ 被覆盖时,Python 如何访问对象属性?

[英]How does Python access an objects attribute when __dict__ is overridden?

The Python docs , specify that attribute access is done via the objects __dict__ attribute. Python 文档,指定属性访问是通过对象__dict__属性完成的。

The default behavior for attribute access is to get, set, or delete the attribute from an object's dictionary.属性访问的默认行为是从对象的字典中获取、设置或删除属性。 For instance, ax has a lookup chain starting with a.__dict__['x'], then type(a).__dict__['x'], and continuing through the base classes of type(a) excluding metaclasses.例如, ax 有一个查找链,以 a.__dict__['x'] 开始,然后是 type(a).__dict__['x'],并继续遍历 type(a) 的基类,不包括元类。 If the looked-up value is an object defining one of the descriptor methods, then Python may override the default behavior and invoke the descriptor method instead.如果查找的值是定义描述符方法之一的对象,则 Python 可能会覆盖默认行为并改为调用描述符方法。 Where this occurs in the precedence chain depends on which descriptor methods were defined.这在优先链中发生的位置取决于定义了哪些描述符方法。

In this example, I override the object's __dict__, but python can still manage to get its attribute, how does that work?:在这个例子中,我覆盖了对象的 __dict__,但是 python 仍然可以设法获取它的属性,它是如何工作的?:

In [1]: class Foo:
   ...:     def __init__(self):
   ...:         self.a = 5
   ...:         self.b = 3
   ...:     def __dict__(self):
   ...:         return 'asdasd'
   ...:

In [2]: obj_foo = Foo()

In [3]: obj_foo.__dict__
Out[3]: <bound method Foo.__dict__ of <__main__.Foo object at 0x111056850>>

In [4]: obj_foo.__dict__()
Out[4]: 'asdasd'

In [5]: obj_foo.b
Out[5]: 3

You are implementing the __dict__ method .您正在实施__dict__方法

If you override the __dict__ attribute you will succeed in breaking Python:如果您覆盖__dict__属性,您将成功破解 Python:

class Foo:
    def __init__(self):
        self.a = 1
        self.__dict__ = {}

Foo().a
AttributeError: 'Foo' object has no attribute 'a'

Interestingly enough, if both are overridden everything is back to normal:有趣的是,如果两者都被覆盖,一切都会恢复正常:

class Foo:
    def __init__(self):
        self.a = 1
        self.__dict__ = {}

    def __dict__(self):
        pass

print(Foo().a)

Outputs输出

 1

Making __dict__ a property also does not seem to break anything:使__dict__成为一个属性似乎也没有破坏任何东西:

class Foo:
    def __init__(self):
        self.a = 1

    @property
    def __dict__(self):
        return {}

print(Foo().a)

Also outputs 1 .还输出1


I suspect the answer to the question *why* lies (probably) deep in the CPython implementation of `object`, more digging needs to be done. 我怀疑*为什么*这个问题的答案(可能)深藏在`object`的CPython实现中,需要做更多的挖掘。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Python如何绕过普通属性查找来找到__dict__? - How does Python bypass normal attribute lookup to find `__dict__`? Python中的属性访问:第一个插槽,然后是__dict__? - Attribute access in Python: first slots, then __dict__? 为什么python __dict__不继承类属性但可以访问它 - why python __dict__ doesnot inherit class attribute but can access it Python 何时从实例 __dict__ 退回到类 __dict__? - When does Python fall back onto class __dict__ from instance __dict__? __dict__在Python中是否存在? - Does __dict__ exist or not in Python? 对象在python3中没有属性&#39;.__ dict__&#39; - Object has no attribute '.__dict__' in python3 如何将属性保留在 __dict__ 之外? - How to keep attribute outside __dict__? Python AttributeError: 'super' object 没有属性 'testnet',但是在 super 上调用 __dict__ 时会出现该属性? - Python AttributeError: 'super' object has no attribute 'testnet', however the attribute appears when __dict__ is called on super? 为什么object()不具有__dict__来支持某些自定义Python类的实例不具有__dict__属性? - Why is `object()` not having `__dict__` to support the instances of some custom Python classes not having a `__dict__` attribute? Python / Django:向UserCreationForm添加自定义字段时出现__dict__属性错误消息 - Python/Django: __dict__ attribute error message when adding custom fields to UserCreationForm
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM