我有一个Base
类,它在其中存储了一些基本方法,属性等,我有一个Mixin
我想在{的一个或多个子类中共享{ {1}}。像这样:
Base
重要的是,我想在class Base(object): pass
class Mixin(object):
# IMPORTANT: cache _x locally on Mixin to only compute for all subclasses
_x = None
@property
def x(self):
if self._x is None:
print 'reset _x'
self._x = 2
return self._x
class A(Base, Mixin): pass
class B(Base, Mixin): pass
上缓存_x
变量,因此它只在所有子类Mixin
,A
等中计算一次.---它需要很长时间才能计算出这个值。奇怪的是,这似乎不像我在python中预期的那样工作:
B
这打印出a = A()
b = B()
print 'calling a.x'
a.x
print 'calling a.x'
a.x
print 'calling b.x'
b.x
print 'calling b.x'
b.x
两次---一次是第一次调用a.x,这是我预期的,第一次调用b.x,这是我没想到的。我对python类属性的理解是它们每个类都存储一次。谁能解释一下这里发生了什么?
是否有更好的模式让reset _x
本地缓存_x
?
答案 0 :(得分:5)
您的问题是您引用了self._x
。这是一个实例属性,即每个实例都不同。如果您没有设置 self._x
,那么Python会使用在继承层次结构中的类上找到的第一个_x
(_x
在Mixin
上self._x
1}} class),但只要设置_x
,就会在该实例上找到Mixin._x
。在新的实例中,该属性不会被设置,因此将使用None
,但它总是Mixin._x
,因为您永远不会更改它。
因此,您希望在self._x
处使用{{1}},但在设置该属性时尤其。