在派生类中访问继承的类变量的dict

时间:2018-10-29 19:37:18

标签: python python-3.x inheritance

假设我们有一个包含一些类变量的基类 x x2 y y2 1 1 1 11 121 2 2 4 12 144 3 3 9 13 169 。此类还具有一个类方法A,该方法用这些变量做一些事情。由于这种行为不应该被硬编码(例如,当添加新的类变量时,我们不想修改foo),因此foo读取foo而不是直接引用变量。
现在我们介绍一个派生类:cls.__dict__扩展了B并添加了更多的类变量,并继承了A。代码示例:

foo

因此,我的问题是:为什么class A: x = 0 y = 1 @classmethod def foo(cls): print([name for name, prop in cls.__dict__.items() if type(prop) is int]) class B(A): z = 3 print(B.x) # prints "0" A.foo() # prints "['x', 'y']" B.foo() # prints "['z']" -- why not "['x', 'y', 'z']"? 不包含从B.__dict__继承的变量,如果不存在,那么它们在哪里?

这不是Accessing class attributes from parents in instance methods的副本,因为我不只是想查询恰好在基类中的特定变量-我想列出它们却不知道他们的名字。这个问题中与MRO相关的答案可能也适用于此,但我认为原始问题有所不同。

1 个答案:

答案 0 :(得分:0)

我用metaclass解决了这个问题,用它重新定义了派生类的创建方式。在这种方法中,我们感兴趣的所有类变量都会从基类复制到派生变量:

class M(type):
  def __new__(cls, name, bases, dct):
    for base in bases:
      for name, prop in base.__dict__.items():
        if type(prop) is int:
          dct[name] = prop
    return super(M, cls).__new__(cls, name, bases, dct)

class A(metaclass=M):
  x = 0
  y = 1
  @classmethod
  def foo(cls):
    print([name for name, prop in cls.__dict__.items() if type(prop) is int])

class B(A):
  z = 3

A.foo()  # prints "['y', 'x']"
B.foo()  # prints "['y', 'x', 'z']"

此外,可以通过以下方式定义元类:foo甚至不必查询__dict__-可以将感兴趣的变量放入列表中,而不用修改__dict__ ,是否应出于某种原因避免这种情况。