python什么时候从实例__ -dict__中倒回____________________________?
请参阅以下片段:
class Foo:
class_var = "hi"
foo = Foo()
assert foo.class_var is Foo.class_var
assert "class_var" in Foo.__dict__
assert "class_var" not in foo.__dict__
所有断言在这里都通过,尽管我不确定身份主张是否通过是否令人惊讶。
python何时以及如何从实例__ dict __ dict __
中回到类__ dict __
?
Please see the below snippet:
class Foo:
class_var = "hi"
foo = Foo()
assert foo.class_var is Foo.class_var
assert "class_var" in Foo.__dict__
assert "class_var" not in foo.__dict__
All assertions here pass, though I am not sure if it's surprising that the identity assertion passes.
When and how does Python fall back onto a class __dict__
from an instance __dict__
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
据我所知,何时将foo.class_var称为以下步骤:
As far as I know when foo.class_var is called the following steps happen:
您应该知道“类属性”和“实例属性”之间的区别,在您的示例中,您具有
class_var
是类属性,在第一个servert语句中,它检查是否class_var
是foo
的实例,它通过,因为foo
是类型foo
,让我们在此处尝试另一个更清晰的示例:请注意,最后一个
断言
语句将引起错误,因为var1
这是类属性,而不是实例属性。You should know the difference between a "class attribute" and an "instance attribute", in your example, you have
class_var
which is class attribute, in the first assert statement, it check ifclass_var
is in the instance ofFoo
, it pass, that becausefoo
is of typeFoo
let's try another more clear examples here:notice something, the last
assert
statement is gonna raise an error, becausevar1
here is a class attribute, not instance attribute.我喜欢以一个示例来解释这一点,因为人们喜欢自己的经历。 带有子类的示例:
您可以想象
getAttr(b,name)
被简化了,例如:探索实例的所有
__ dict __ dict __
和所有类:cristifat的答案是精确的,但对于每个人来说都不够容易。
I like to explain it by an example becase people like their own experience. Example with a subclass:
You can imagine that
getattr(b, name)
is implemented simplified like:Explore all
__dict__
of the instance and all classes:The CristiFat's answer is precise, but maybe not easy enough for everybody.
根据(已经提到的) (重点是我的):
类定义内定义的属性(但是在初始化器(或其他方法)之外)称为类属性,并且绑定到类本身而不是其实例 。就像 static 的成员来自 c ++ 或 java 。 [python.docs] EM> 强调 仍然是我的):
因此,属性查找顺序可以像以下(按升序顺序进行曲线,当找到属性名称时,只需返回其值(因此忽略其余的条目))。 (内置) __ getAttribute __ 方法:
描述符(如果有的话)
实例命名空间( foo .__ dict __ dict __ )))
实例类命名空间( foo .__ dict __ dict __ )))
实例类base类名称空间(
e .__ dict __ for e in in foo .__ mro .__ mro __
)custom __getAttr__方法可能返回
的任何东西
通常发生的事情,就像 python 是可以更改的高度自定义的( eg eg ) __ slots __ )。
对于确切的行为,您可以检查源代码( [github]:python/cpython-- (main)cpython/objects ):
typeObject.c : type_getattro (Optionaly: super_getattro em>, slot_tp_getattro )
object.c : _pyobject_genericgetAttrwithDict
以下是一个示例,可以清除(希望)。
code00.py :
输出:
According to (already mentioned) [Python.Docs]: Data model (emphasis is mine):
Attributes defined inside a class definition (but outside the initializer (or other methods)) are called class attributes, and are bound to the class itself rather than its instances. It's like static members from C++ or Java. [Python.Docs]: Compound statements - Class definitions states (emphasis still mine):
So, the attribute lookup order can be summarized like below (traverse in ascending order, when attribute name found simply return its value (therefore ignoring the remaining entries)). The first steps performed by the (builtin) __getattribute__ method:
Descriptors (if any - note that their presence could also be triggered indirectly (by other features))
Instance namespace (foo.__dict__)
Instance class namespace (Foo.__dict__)
Instance class base classes namespaces (
e.__dict__ for e in Foo.__mro__
)Anything that a custom __getattr__ method might return
The above is what typically happens, as Python being highly customizable that can be altered (e.g. __slots__).
For an exact behavior, you could check the source code ([GitHub]: python/cpython - (main) cpython/Objects):
typeobject.c: type_getattro (optionally: super_getattro, slot_tp_getattro)
object.c: _PyObject_GenericGetAttrWithDict
Here's an example that will clear things up (hopefully).
code00.py:
Output: