在Python中从父级访问子级的__dict__?

Nat*_*ate 1 python oop class

我有一个课程,我希望能够检查其成员并列出它们.但是,我只是要继承它(在C++中这将是一个抽象类),所以我希望这个方法也返回其子类中的成员.

这是可能的,甚至是Python中的好主意?跟进,这可能没有inspect模块吗?

像这样:

class A:
    @staticmethod
    def GetMembers():
        return dict(vars(A))

class B(A):
    FOO = 'foobar'
    BAR = 'barfoo'
Run Code Online (Sandbox Code Playgroud)

但是,测试显示:

>>> A.GetMembers()
{'__module__': '__main__', '__doc__': None, 'GetMembers': <staticmethod object at 0x02219BB0>}
>>> B.GetMembers()
{'__module__': '__main__', '__doc__': None, 'GetMembers': <staticmethod object at 0x02219BB0>}
>>> dict(vars(B))
{'__module__': '__main__', 'FOO': 'foobar', 'BAR': 'barfoo', '__doc__': None}
Run Code Online (Sandbox Code Playgroud)

我想B.GetMembers()包括FOOBAR喜欢dict(vars(B))做.

Jor*_*ley 5

@staticmethods没有意识到类和类范围......所以静态方法无法知道它是否在子类上调用.

@classmethods接受他们的类类型作为第一个参数(就像instancemethods将self作为第一个参数)...然后你可以调用它的cls.

class A:
    @classmethod
    def GetMembers(cls):
        return dict(vars(cls))

class B(A):
    FOO = 'foobar'
    BAR = 'barfoo'
Run Code Online (Sandbox Code Playgroud)

测试

>>> A.GetMembers()
{'__module__': '__main__', '__doc__': None, 'GetMembers': <classmethod object at
 0x0286D130>}
>>> B.GetMembers()
{'__module__': '__main__', 'FOO': 'foobar', 'BAR': 'barfoo', '__doc__': None}
>>>
Run Code Online (Sandbox Code Playgroud)

或者您也可能想要访问父类dicts.从类(或实例)方法,您可以通过访问基类cls.__bases__

class A:
    @classmethod
    def GetMembers(cls):
      d = dict()
      for basecls in cls.__bases__:
        if hasattr(basecls,"GetMembers"):
          d.update(basecls.GetMembers()) #call inherited GetMembers
        else:
          d.update(dict(vars(basecls))) #no GetMembers inherited from basecls so just get its vars
      d.update( dict(vars(cls)))
      return d

>>> class B(A):
...     FOO = 'foobar'
...     BAR = 'barfoo'
...
>>> class C(A):
...     FOOBAR = "whatever"
...
>>> class X(B,A):
...     FOO = 'foobar2'
...     COLOR = 'red'
...
>>> class X(B,C):
...     FOO = 'foobar2'
...     COLOR = 'red'
...
>>> X.GetMembers()
{'__module__': '__main__', 'BAR': 'barfoo', 'COLOR': 'red', 'FOOBAR': 'whatever'
, 'FOO': 'foobar2', '__doc__': None}
Run Code Online (Sandbox Code Playgroud)