这是一个完全理论上的问题。假设下面的代码:对象与类变量
>>> class C:
... a = 10
... def f(self): self.a = 999
...
>>>
>>> C.a
10
>>> c = C()
>>> c.a
10
>>> c.f()
>>> c.a
999
在这一点上,是类变量C.a
通过对象c
仍然可以访问?
这是一个完全理论上的问题。假设下面的代码:对象与类变量
>>> class C:
... a = 10
... def f(self): self.a = 999
...
>>>
>>> C.a
10
>>> c = C()
>>> c.a
10
>>> c.f()
>>> c.a
999
在这一点上,是类变量C.a
通过对象c
仍然可以访问?
是的,虽然c.__class__.a
或type(c).a
。这两者在旧式课程中稍有不同(希望那些现在都已经死了 - 但你永远不知道......)有type()
的<type 'instance'>
(和__class__
按预期工作),而对于新式课程,type()
是相同的到__class__
除非对象覆盖属性访问权限。
所有类变量都可以通过从该类实例化的对象访问。
>>> class C:
... a = 10
... def f(self): self.a = 999
...
>>> C.a
10
>>> c = C()
>>> c.a
10
>>> c.f()
>>> c.a
999
>>> c.__class__.a
10
>>> c.a
999
>>> del(c.a)
>>> c.a
10
属性首先在对象命名空间中搜索,然后在类中搜索。
是的,您可以从对象c
,àla c.a
访问a
。该值最初将10
但是,如果调用c.f()
的c.a
值现在是999,但C.a
仍将10.同样的,如果你现在更改C.a
,比方说,1000,c.a
仍然是999
基本上,当实例的C
一个实例,它将使用类变量作为自己的a
值,直到您更改该实例的a
的价值,在这种情况下,将不再“分享”a
同班同学。
在类实例上分配给它之后,同时存在名为a
的类属性和名为a
的实例属性。我说明:
>>> class Foo(object):
... a = 10
...
>>> c = Foo()
>>> c.a
10
>>> c.a = 100 # this doesn't have to be done in a method
>>> c.a # a is now an instance attribute
100
>>> Foo.a # that is shadowing the class attribute
10
>>> del c.a # get rid of the instance attribute
>>> c.a # and you can see the class attribute again
10
>>>
不同的是,存在一个在Foo.__dict__
一个条目,而另一个存在如在c.__dict__
一个条目。当您访问instance.attribute
时,如果它存在,则返回instance.__dict__['attribute']
,如果不存在,则检查type(instance).__dict__['attribute']
。然后检查该类的超类,但稍微复杂一些。
但无论如何,主要的一点是它不一定是一个或另一个。一个类和一个实例可以具有不同的具有相同名称的属性,因为它们存储在两个单独的字典中。
这是这里最清楚的解释。谢谢你的回答。 – 2010-10-12 21:36:18
你试过了,它工作。这不是理论上的。这甚至不是一个真正的问题。有效。你还想知道什么? – 2010-10-12 21:32:49
我想知道什么? “在这一点上,类变量C.a仍然可以通过对象c访问吗?” – 2010-10-13 04:40:31