14

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

>>> class A(object):
...     x = 4
...
>>> a = A()
>>> a.x
4

很容易证明a.x确实是解析为A.x,而不是在构造过程中复制到实例:

>>> A.x = 5
>>> a.x
5

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

class MyClass:
    """A simple example class"""
    i = 12345
    def f(self):
        return 'hello world'

[剪辑]

...根据定义,作为函数对象的类的所有属性都定义了其实例的相应方法。所以在我们的例子中,x.fis 是一个有效的方法引用,sinceMyClass.f是一个函数,但x.i不是,sinceMyClass.i不是。...

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

我的问题是,这有记录吗?我可以依靠这种行为吗?

4

2 回答 2

13

参考http://docs.python.org/reference/datamodel.html中的ClassesClass instances部分

一个类有一个由字典对象实现的命名空间。类属性引用被翻译成这个字典中的查找,例如,Cx 被翻译成 C.__dict__["x"] (尽管特别是对于新式类,有许多钩子允许其他定位属性的方法)

类实例是通过调用类对象创建的(见上文)。类实例具有作为字典实现的命名空间,这是搜索属性引用的第一个位置。如果在那里找不到属性,并且实例的类具有该名称的属性,则使用类属性继续搜索。

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

于 2012-04-25T10:11:59.517 回答
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自动传递。您可能使用了其他旨在存储为类属性并在实例上查找的对象;properties 是一个示例(property如果您不熟悉内置函数,请查看它。)

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

于 2012-04-25T12:25:31.847 回答