关于范围:Python:通过实例访问类变量

Python: access class variables via instance

在python中,可以通过类实例访问类变量:

1
2
3
4
5
6
>>> class A(object):
...     x = 4
...
>>> a = A()
>>> a.x
4

很容易看出,a.x实际上是解析为a.x的,而不是在构建过程中复制到实例:

1
2
3
>>> A.x = 5
>>> a.x
5

尽管这种行为是众所周知和广泛使用的,但我找不到任何关于它的权威文档。在python文档中,我能找到的最接近的是关于类的部分:

1
2
3
4
5
class MyClass:
   """A simple example class"""
    i = 12345
    def f(self):
        return 'hello world'

[snip]

... By definition, all attributes of a class that are function objects define corresponding methods of its instances. So in our example, x.f is a valid method reference, since MyClass.f is a function, but x.i is not, since MyClass.i is not. ...

然而,这部分专门讨论方法,因此它可能与一般情况无关。

我的问题是,这是文件吗?我能依赖这种行为吗?


在http://docs.python.org/reference/datamodel.html中引用ClassesClass instances部分

A class has a namespace implemented by a dictionary object. Class
attribute references are translated to lookups in this dictionary,
e.g., C.x is translated to C.__dict__["x"] (although for new-style classes in particular there are a number of hooks which allow for other means of locating attributes)

A class instance is created by calling a class object (see above). A
class instance has a namespace implemented as a dictionary which is
the first place in which attribute references are searched. When an
attribute is not found there, and the instance’s class has an
attribute by that name, the search continues with the class
attributes.

一般来说,这种用法是很好的,除了"新样式类"中提到的特殊情况,特别是有许多钩子,允许使用其他方法来定位属性。


你不仅可以依靠这种行为,还可以经常这样做。

想想方法。方法只是一个已成为类属性的函数。然后在实例中查找它。

1
2
3
4
5
6
7
8
>>> def foo(self, x):
...     print"foo:", self, x
...
>>> class C(object):
...     method = foo # What a weird way to write this! But perhaps illustrative?
...
>>> C().method("hello")
foo: <__main__.C object at 0xadad50> hello

对于像函数这样的对象,这不是一个简单的查找,但是自动传递self会产生一些魔力。您可能使用了其他要作为类属性存储并在实例上查找的对象;属性就是一个例子(如果您不熟悉,请查看property内置项)。

正如OKM所指出的,这种工作方式在数据模型参考(包括有关使方法和属性工作的魔力的更多信息和链接)中进行了描述。到目前为止,数据模型页是语言引用中最有用的部分;它还包括几乎所有__foo__方法和名称的文档。