这是一个完全理论上的问题。假设以下代码:
>>> 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
吗?
答案 0 :(得分:4)
是的,不过c.__class__.a
或type(c).a
。这两者在旧式课程中有所不同(希望,那些现在已经全部死亡 - 但你永远不知道......)有type()
<type 'instance'>
(而__class__
的作用是对于新式类,type()
与__class__
相同,除非对象覆盖属性访问。
答案 1 :(得分:1)
所有类变量都可以通过从该类实例化的对象访问。
>>> 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
首先在对象命名空间中搜索属性,然后在类中搜索。
答案 2 :(得分:1)
是的,您可以从对象a
,àlac
访问c.a
。该值最初为10。
但是,如果您拨打c.f()
,c.a
的值现在为999,但 C.a
仍为10.同样,如果你现在将C.a
更改为1000,c.a
仍为999。
基本上,当您实例化C
的实例时,它将使用类变量作为其自己的a
值,直到您更改该实例的值{{ 1}},在这种情况下,它将不再与该类“共享”a
。
答案 3 :(得分:1)
在类实例上为其分配后,同时存在名为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']
,如果不存在,则会检查{{1}}。然后检查类的超类,但稍微复杂一点。
但无论如何,重点是它不必是一个或另一个。类和实例都可以具有相同名称的不同属性,因为它们存储在两个单独的序列中。