Python超类反射
时间:2020-03-05 18:42:45 来源:igfitidea点击:
如果我有Python代码
class A(): pass class B(): pass class C(A, B): pass
并且我有类" C",有没有办法遍历它的超类(" A"和" B")?伪代码之类的东西:
>>> magicGetSuperClasses(C) (<type 'A'>, <type 'B'>)
一种解决方案似乎是inspect模块和getclasstree
函数。
def magicGetSuperClasses(cls): return [o[0] for o in inspect.getclasstree([cls]) if type(o[0]) == type]
但这是达到目标的" Pythonian"方法吗?
解决方案
回答
C .__ bases__是超类的数组,因此我们可以像这样实现假设功能:
def magicGetSuperClasses(cls): return cls.__bases__
但是我想在大多数情况下直接引用cls .__ bases__
会更容易。
回答
@John:代码段无效-我们正在返回基类的类(也称为元类)。我们真的只想要cls .__ bases__
:
class A: pass class B: pass class C(A, B): pass c = C() # Instance assert C.__bases__ == (A, B) # Works assert c.__class__.__bases__ == (A, B) # Works def magicGetSuperClasses(clz): return tuple([base.__class__ for base in clz.__bases__]) assert magicGetSuperClasses(C) == (A, B) # Fails
另外,如果我们使用的是Python 2.4+,则可以使用生成器表达式而不是创建列表(通过[]),然后将其变成一个元组(通过tuple
)。例如:
def get_base_metaclasses(cls): """Returns the metaclass of all the base classes of cls.""" return tuple(base.__class__ for base in clz.__bases__)
那是一个令人困惑的例子,但是Genexps通常很容易并且很酷。 :)
回答
inspect模块是一个好的开始,请使用getmro函数:
Return a tuple of class cls’s base classes, including cls, in method resolution order. No class appears more than once in this tuple. ...
>>> class A: pass >>> class B: pass >>> class C(A, B): pass >>> import inspect >>> inspect.getmro(C)[1:] (<class __main__.A at 0x8c59f2c>, <class __main__.B at 0x8c59f5c>)
返回的元组的第一个元素是C,我们可以忽略它。
回答
如果我们需要知道super()调用类的顺序,则可以使用C .__ mro__,因此不需要"检查"。