[英]Object vs. class variable
This is a completely theoretical question. 这是一个完全理论化的问题。 Suppose the following code:
假设以下代码:
>>> class C:
... a = 10
... def f(self): self.a = 999
...
>>>
>>> C.a
10
>>> c = C()
>>> c.a
10
>>> c.f()
>>> c.a
999
At this point, is class variable Ca
still accessible through the object c
? 此时,类变量
Ca
仍可通过对象c
访问吗?
Yes, though c.__class__.a
or type(c).a
. 是的,虽然
c.__class__.a
或type(c).a
。 The two differ slightly in that old-style classes (hopefully, those are all dead by now - but you never know...) have a type()
of <type 'instance'>
(and __class__
works as expected) while for new-style classes, type()
is identical to __class__
except when the object overrides attribute access. 两者的区别在于旧式的类(希望,那些现在都已经死了 - 但你永远不知道......)有一个
<type 'instance'>
__class__
<type 'instance'>
的type()
(和__class__
按预期工作)而对于new样式类, type()
与__class__
相同,除非对象覆盖属性访问。
All class variables are accessible through objects instantiated from that 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
Attributes are first searched within the object namespace and then class. 首先在对象命名空间中搜索属性,然后在类中搜索。
Yes, you can access a
from an object c
, à la ca
. 是的,你可以访问
a
从对象c
,点菜ca
。 The value would initially be 10. 该值最初为10。
However, if you call cf()
, the value of ca
will now be 999, but Ca
will still be 10. Likewise, if you now change Ca
to, say, 1000, ca
will still be 999. 但是,如果你调用
cf()
, ca
的值现在将是999, 但是 Ca
仍然是10.同样,如果你现在将Ca
改为1000,那么ca
仍然是999。
Basically, when you instantiate an instance of C
, it will use the class variable as its own a
value, until you change the value of that instance's a
, in which case it will no longer "share" a
with the class. 基本上,当您实例化
C
的实例时,它将使用类变量作为其自己a
值, 直到您更改该实例的值a
,在这种情况下,它将不再与该类“共享” a
。
After you assign to it on the class instance, there is both a class attribute named a
and an instance attribute named a
. 后分配给它的类的实例,有两个命名类属性
a
和命名实例属性a
。 I illustrate: 我举例说明:
>>> 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
>>>
The difference is that one exists as an entry in Foo.__dict__
and the other exists as an entry in c.__dict__
. 不同之处在于,一个作为
Foo.__dict__
中的条目存在,另一个作为c.__dict__
的条目存在。 When you access instance.attribute
, instance.__dict__['attribute']
is returned if it exists and if not then type(instance).__dict__['attribute']
is checked. 当你访问
instance.attribute
,如果它存在,则返回instance.__dict__['attribute']
,如果不存在,则返回type(instance).__dict__['attribute']
。 Then the superclasses of the class are checked but that gets slightly more complicated. 然后检查类的超类,但稍微复杂一点。
But at any rate, the main point is that it doesn't have to be one or the other. 但无论如何,重点是它不必是一个或另一个。 A class and an instance can both have distinct attributes with identical names because they are stored in two separate dicts.
类和实例都可以具有相同名称的不同属性,因为它们存储在两个单独的dicts中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.