2012-04-25 82 views
13

在Python中,类变量可以通过该类的实例访问:的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不是。 ...

但是,这部分具体谈到方法,所以它可能与一般情况无关。

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

回答

13

参考文献的ClassesClass instanceshttp://docs.python.org/reference/datamodel.html

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

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

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

7

你不仅可以依靠这种行为,你可以不断地做。

想想方法。一个方法仅仅是一个已经被作为类属性的函数。然后,您会查看实例。

>>> 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__方法和名称的文档。

+0

+1为方法的新视图,但我已经写在过去的大部分代码,现在看起来更诡异和更脆弱;感谢那 :-/ – 0xc0de 2016-01-19 08:39:50