python Python超类反射
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25807/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python super class reflection
提问by jelovirt
If I have Python code
如果我有 Python 代码
class A():
pass
class B():
pass
class C(A, B):
pass
and I have class C
, is there a way to iterate through it's super classed (A
and B
)? Something like pseudocode:
我有类C
,有没有办法遍历它的超类(A
和B
)?类似伪代码的东西:
>>> magicGetSuperClasses(C)
(<type 'A'>, <type 'B'>)
One solution seems to be inspect moduleand getclasstree
function.
一种解决方案似乎是检查模块和getclasstree
功能。
def magicGetSuperClasses(cls):
return [o[0] for o in inspect.getclasstree([cls]) if type(o[0]) == type]
but is this a "Pythonian" way to achieve the goal?
但这是实现目标的“Pythonian”方式吗?
回答by John
C.__bases__
is an array of the super classes, so you could implement your hypothetical function like so:
C.__bases__
是一个超类的数组,所以你可以像这样实现你的假设函数:
def magicGetSuperClasses(cls):
return cls.__bases__
But I imagine it would be easier to just reference cls.__bases__
directly in most cases.
但我想cls.__bases__
在大多数情况下直接引用会更容易。
回答by cdleary
@John: Your snippet doesn't work -- you are returning the classof the base classes (which are also known as metaclasses). You really just want cls.__bases__
:
@约翰:您的片段不工作-你正在返回的类的基类(也被称为元类)的。你真的只想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
Also, if you're using Python 2.4+ you can use generator expressionsinstead of creating a list (via []), then turning it into a tuple (via tuple
). For example:
此外,如果您使用的是 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__)
That's a somewhat confusing example, but genexps are generally easy and cool. :)
这是一个有点令人困惑的例子,但 genexps 通常既简单又酷。:)
回答by Torsten Marek
The inspect module was a good start, use the getmrofunction:
检查模块是一个好的开始,使用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. ...
按方法解析顺序返回类 cls 的基类的元组,包括 cls。在这个元组中没有类出现多次。...
>>> 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>)
The first element of the returned tuple is C
, you can just disregard it.
返回的元组的第一个元素是C
,你可以忽略它。
回答by sinzi
if you need to know to order in which super() would call the classes you can use C.__mro__
and don't need inspect
therefore.
如果您需要知道在哪个 super() 调用您可以使用C.__mro__
但不需要的类的顺序inspect
。