简体   繁体   English

对象与类变量

[英]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__.atype(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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM