2009-09-09 107 views
89

給定一個類Foo(不管它是否爲new-style類),如何生成全部基類 - 繼承層次結構中的任何位置 - 它是否爲issubclass列出給定類的層次結構中的所有基類?

+1

給定一個類對象('type'將會是更好的術語)'isinstance'將不起作用...或者你的意思是'issubclass'或者你想要一個實例;-p – 2009-09-09 20:21:45

+0

謝謝;我編輯了這篇文章。 – 2009-09-09 20:39:33

回答

127

inspect.getmro(cls)既適用於新老樣式類,並返回相同NewClass.mro() :該類及其所有祖先類的列表,按照用於方法解析的順序。

>>> class A(object): 
>>>  pass 
>>> 
>>> class B(A): 
>>>  pass 
>>> 
>>> import inspect 
>>> inspect.getmro(B) 
(<class '__main__.B'>, <class '__main__.A'>, <type 'object'>) 
+1

幹得好:http://docs.python.org/library/inspect.html#inspect.getmro – 2009-09-09 20:44:22

+1

不工作對於pyobjc類:( 文件「/Users/rbp/Projects/zzzzzzz/macmdtypes.py」,第70行,強制 print inspect.getmro(path) 文件「/System/Library/Frameworks/Python.framework/版本/ 2.7/lib/python2.7/inspect.py「,第348行,在getmro _searchbase(cls,result) 文件」/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7 /inspect.py」,線路339,在_searchbases 用於CLS基.__ bases__: AttributeError的: '__NSTaggedDate' 對象沒有屬性 '__bases__來得到' – rbp 2013-08-08 17:11:45

+7

@rbp我SUS PECT,你有,我遇到了同樣的問題:你試圖做'inspect.getmro(OBJ)',而不是'inspect.getmro(類型(OBJ))'。 – esmit 2015-07-09 18:40:48

13

可以使用__bases__元組對象的類:

class A(object, B, C): 
    def __init__(self): 
     pass 
print A.__bases__ 

通過__bases__返回的元組具有其所有的基類。

希望它有幫助!

24

inspect.getclasstree()將創建一個類和它們的基礎的嵌套列表。 用法:

inspect.getclasstree(inspect.getmro(IOError)) # Insert your Class instead of IOError. 
+1

哦,很好。而爲了更好的輸出,請使用pprint! 'python -c'導入檢查;來自pprint import pprint as pp; PP(inspect.getclasstree(inspect.getmro(IO錯誤)))'' – penguin359 2016-11-15 04:58:55

28

__bases__ property可在一個python class,其中包含了基礎類的元組:

>>> def classlookup(cls): 
...  c = list(cls.__bases__) 
...  for base in c: 
...   c.extend(classlookup(base)) 
...  return c 
... 
>>> class A: pass 
... 
>>> class B(A): pass 
... 
>>> class C(object, B): pass 
... 
>>> classlookup(C) 
[<type 'object'>, <class __main__.B at 0x00AB7300>, <class __main__.A at 0x00A6D630>] 
+2

這可能引入重複。這就是爲什麼'getmro'的文檔明確說「沒有類在這個元組中多次出現」? – 2009-09-09 20:45:25

+2

注意,'__bases__'只到達**一個級別**。 (當你的遞歸效用暗示,但在例如粗略地看一眼可能不會對回暖。) – 2016-03-18 14:31:11

1

儘管約亨的答案是非常有益的,正確的,因爲你可以用獲得的類層次結構。該檢查模塊的getmro()方法,它也必須強調的是Python的繼承層次如下:

例如:

class MyClass(YourClass): 

繼承類

  • 兒童類
  • 派生類
  • 子類

例如:

class YourClass(Object): 

繼承的類

  • 父類
  • 基類
  • 超類

一類可以從另一個 繼承 - 類歸因繼承 - 特別是,它的方法是遺傳 - 這意味着一個繼承(子)類的實例都可以訪問歸因繼承(父)類的

實例 - >類 - >然後繼承類

使用

import inspect 
inspect.getmro(MyClass) 

會顯示您的層次結構,內Python的。