__dict__不了解某个类的某些属性

Eri*_*uld 4 python class python-3.x

如果我上课

class MyClass:
    """A simple example class"""
    i = 12345

    def f(self):
        return 'hello world'
Run Code Online (Sandbox Code Playgroud)

然后在控制台中说

x=MyClass()
x.counter = 1
vars(x) # returns {'counter': 1}
x.__dict__ # returns {'counter': 1}
Run Code Online (Sandbox Code Playgroud)

为什么不知道x的i属性?我确信这是因为我对我在Python中如何定义类的各种属性的误解.

在这方面,Python 2/3之间有什么区别吗?打电话dir(x)给了我所有我期望的东西.

我怀疑其他初学者已经问过这个问题,但在这个阶段我不知道在问题标题中寻找正确的事情.网站建议的所有内容都不正确.

cs9*_*s95 5

i被定义为的属性,而不是实例.您将看到只存在一个版本的MyClass.i所有实例MyClass:

In [133]: x = MyClass()

In [134]: y = MyClass()

In [135]: x.i, y.i, MyClass.i
Out[135]: (12345, 12345, 12345)

In [136]: MyClass.i = 54321

In [137]: x.i, y.i, MyClass.i
Out[137]: (54321, 54321, 54321)
Run Code Online (Sandbox Code Playgroud)

你也会发现i里面坐得很好MyClass.__dict__:

In [138]: vars(MyClass)
Out[138]: 
mappingproxy({'__dict__': <attribute '__dict__' of 'MyClass' objects>,
              '__doc__': 'A simple example class',
              '__module__': '__main__',
              '__weakref__': <attribute '__weakref__' of 'MyClass' objects>,
              'f': <function __main__.MyClass.f>,
              'i': 54321})    # <------
Run Code Online (Sandbox Code Playgroud)

请注意,类属性的另一个有趣特性是它们不与实例属性冲突:

In [148]: class MyClass:
     ...:     i = 12345
     ...:     def __init__(self):
     ...:         self.i = 54321
     ...:         

In [149]: x = MyClass()

In [150]: MyClass.i, x.i
Out[150]: (12345, 54321)
Run Code Online (Sandbox Code Playgroud)