Python:通过实例访问类变量

时间:2012-04-25 10:06:03

标签: python scope specifications

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

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

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

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

尽管这种行为是well known并且被广泛使用,但我找不到任何涵盖它的权威文档。我在Python文档中找到的最接近的是section on classes

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

[剪断]

     

...根据定义,作为函数对象的类的所有属性都定义其实例的相应方法。因此,在我们的示例中,x.f是一个有效的方法引用,因为MyClass.f是一个函数,但x.i不是,因为MyClass.i不是。{{1}}。 ...

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

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

2 个答案:

答案 0 :(得分:13)

参考http://docs.python.org/reference/datamodel.html

中的ClassesClass instances部分
  

类具有由字典对象实现的命名空间。类   属性引用被转换为此字典中的查找,   例如,C.x被翻译为C .__ dict __ [“x”](尽管对于新式类,特别是有许多钩子允许其他方法来定位属性)

     

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

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

答案 1 :(得分: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所说,它的工作方式在data model reference中有所描述(包括有关使方法和属性有效的魔法的更多信息的信息和链接)。 “数据模型”页面是迄今为止语言参考中最有用的部分;它还包括几乎所有__foo__方法和名称的文档。