追加"而非覆盖超类实例变量

0 投票
2 回答
662 浏览
提问于 2025-04-17 03:53

在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

撰写回答