在 __dict__ 中找不到 python 中的类变量

Posted

技术标签:

【中文标题】在 __dict__ 中找不到 python 中的类变量【英文标题】:Class variables in python not found in __dict__ 【发布时间】:2013-06-08 19:35:13 【问题描述】:

有一个代码:

class C():
    a=1
    def f(self):
        print "f func"

a=C()
print a.a
a.f()
>>> 1
>>> f func

当我尝试获取a.__dict__vars(a) 时,它只显示。 但是

a.b=123
print a.__dict__
>>> 'b': 123

我不明白,为什么会这样。

【问题讨论】:

【参考方案1】:

查看a.__dict__vars(a) 可以得到a 的属性,这是一个实例。该实例最初没有自己的属性。您在类定义中创建的属性a 是类本身的属性,而不是其实例的属性。稍后当您执行a.b = 123 时,您只在实例上创建了一个属性,因此您可以在实例__dict__ 中看到它。如果您查看C.__dict__,您将看到属性a

当您执行print a.a 时,Python 会动态查找类C 上的属性a。它看到实例没有属性a,所以它查看类并在那里找到一个。那就是打印的值。创建实例时,类属性不会“复制”到实例;相反,每次您尝试读取实例属性时,Python 都会检查它是否存在于实例中,如果不存在,则会在类中查找它。

【讨论】:

这可能有助于解释为什么print a.a 打印 1,这可能是一个混淆点。【参考方案2】:
>>> C.a
1
>>> vars(C)['a']
1

(一个类的整个vars 字典相当长。)

正如你的标题所说,它是一个类变量。它属于类,而不是对象。当您调用a.a 时,Python 会在后台执行一些特殊逻辑来为您查看类型对象。我不是专家,但我怀疑它找到a 的方式与它找到方法的方式相同。在 Java 等语言中,我认为不鼓励这种用法。我不知道在 Python 中是否不鼓励这样做。

【讨论】:

以上是关于在 __dict__ 中找不到 python 中的类变量的主要内容,如果未能解决你的问题,请参考以下文章

PyCharm 在 __init__.py 中找不到任何 OpenCV 函数的引用

__init__.py 在同一目录中找不到模块[重复]

python __dict__

Python 在同一文件夹中找不到模块

Flyway:在 [classpath:db/migration] 中找不到迁移位置

为啥从 Python 中的对象继承,在不指定父对象时更改 __dict__ 的类型不会? [复制]