对象与类变量

时间:2010-10-12 20:30:44

标签: python syntax theory

这是一个完全理论上的问题。假设以下代码:

>>> 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吗?

4 个答案:

答案 0 :(得分:4)

是的,不过c.__class__.atype(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}}。然后检查类的超类,但稍微复杂一点。

但无论如何,重点是它不必是一个或另一个。类和实例都可以具有相同名称的不同属性,因为它们存储在两个单独的序列中。