见下面的例子。将__class__前缀与类实例'object'一起使用可得到预期的结果。为什么类变量在没有__class__前缀的类实例'c()'中甚至可用?它在什么情况下使用?
>>> class c:
x=0
>>> c.x
0
>>> c().x
0
>>> c().__class__.x
0
>>> c.x += 1
>>> c.x
1
>>> c().x += 1
>>> c.x
1
>>> c().__class__.x += 1
>>> c.x
2
>>>
答案 0 :(得分:2)
为什么类变量是偶数 可在类实例'c()'处获得 没有 class 前缀?
您可以将其视为“继承”其类的实例。 IOW,当在实例'atr'
上查找名为x
的属性时(例如通过x.atr
),除非在实例本身中找到它,否则它将在类中查找(这可能反过来导致在类的基础上查找,在mro
链上。)
在什么情况下使用?
最常见的单一案例:
class sic(object):
def foo(self): ...
x = sic()
x.foo()
您可能不会将foo
视为“类变量”,但那是因为术语“变量”在Python中确实毫无意义,而是处理名称和属性。在给定的词法范围内,可调用和不可调用对象没有单独的命名空间:它们共享相同的命名空间。
因此,举例来说,如果您执行了x.foo = 23
,则无法再调用x.foo()
- 因为x.foo
的查找会为您提供值23
,这是一个int
,不可调用。
另一种看待这个的方法是
class one(object):
foo = lambda self: ...
class two(object):
def foo(self): ...
class three(object):
foo = 23
目前没有深刻的区别 - 它们都是设置类属性foo
的一种方式(一个不可调用,两个是;一个绑定def
语句,两个绑定;有差异在这些类的实例上进行属性查找时不深。)
不可调用属性的典型用法可能是:
class zap(zop):
zep = None
def blub(self):
if self.zep is None: self.zep = 23
...&c...
无需zap
__init__
self.zep = None
和__init__
以及授权超级类zop
(如果有) - 只需继承__init__
'blub
(如果有的话)并且只要可行就使用class属性(当且仅当在该实例上调用blub
时,它将成为实例属性 - 也可以节省一点点用于永远不会调用{{1}}的实例的内存; - )。