追加"而非覆盖超类实例变量
在Python中,有没有办法做到像这样呢?
class A():
var = "1, 2, 3"
class B():
var = ... ", 4"
instance = B()
instance.var # = 1, 2, 3, 4
2 个回答
1
你不能直接添加东西,而是要替换,但你可以用一个包含原始内容的表达式来替换:
class A(object):
var = "1, 2, 3"
class B(A):
var = A.var + ", 4"
instance = B()
instance.var # = 1, 2, 3, 4
这对于简单的使用场景已经够了,但一个更有趣的解决方案是使用描述符;最简单的方法是用 property
。
class A(object):
var = "1, 2, 3"
class B(A):
_subvar = ", 4"
@property
def var(self):
return super(B, self).var + self._subvar
instance = B()
instance.var # = 1, 2, 3, 4
这对 B
的实例有效,但对 B
本身(就像第一个例子那样)无效。要想让它在 B
本身上也能用,你需要自己实现一个描述符:
class Appender(object):
def __init__(self, cls, attr):
self.cls = cls
self.attr = attr
def __get__(self, instance, owner):
var = super(self.cls, owner).var
return var + getattr(self.cls, self.attr)
class B(A):
_realvar = ', 4'
B.var = Appender(B, '_realvar')
这样在类上和类的实例上都能同样有效。
4
问题中给出的例子没有使用父类,也没有使用实例变量。从问题的标题来看,你可能是想同时使用这两者。下面是一个它是如何工作的例子:
class A(object):
def __init__(self):
self.var = "1,2,3"
class B(A):
def __init__(self):
super(B,self).__init__()
self.var += ",4,5"
print A().var
print B().var
请注意,你的例子只是把属性分配给没有关系的类,实际上是把这些类当作命名空间来用。这是完全可以理解的,但并不是你最初想要的:
class A:
var = "1,2,3"
class B:
var = A.var + ",4,5"
print A.var
print B.var