指定されたクラスの階層内のすべての基本クラスをリストしますか?


回答:


196

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'>)

2
pyobjcクラスでは機能しません:( File "/Users/rbp/Projects/zzzzzzz/macmdtypes.py"、line 70、in coerce print inspect.getmro(path)File "/System/Library/Frameworks/Python.framework/ getmro searchbases (cls、result)ファイルの Versions / 2.7 / lib / python2.7 / inspect.py "、行348、" / System / Library / Frameworks / Python.framework / Versions / 2.7 / lib / python2.7 / inspect cls .__ bases_のベースの_searchbasesの.py "、339行目:AttributeError: ' NSTaggedDate' object has no attribute '__bases '
rbp

17
あなたがしようとしていた:私はあなたが私が遭遇したのと同じ問題を抱えていたと思われる@rbp inspect.getmro(obj)の代わりにinspect.getmro(type(obj))
2015

44

基本クラスのタプルを含むpython で利用可能な__bases__プロパティを参照してください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>]

5
これにより重複が発生する可能性があります。そして、これがのドキュメントにgetmro「このタプルにクラスは2回以上出現しない」と明記されているのはなぜですか?
Sridhar Ratnakumar

10
注意、1レベル__bases__上がるだけです。(再帰的なユーティリティが暗示するように、例では大まかな一見がそれを理解しないかもしれません。)
ボブ・スタイン

32

inspect.getclasstree()クラスとそのベースのネストされたリストを作成します。使用法:

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

1
ああ、いいね。さらに優れた出力を得るには、pprintを使用してください!python -c 'import inspect; from pprint import pprint as pp; pp(inspect.getclasstree(inspect.getmro(IOError)))'
ペンギン359 2016年

20

あなた__bases__はクラスオブジェクトのタプルを使うことができます:

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

によって返されるタプルには、__bases__すべての基本クラスがあります。

それが役に立てば幸い!


クラスがクラスから継承するクラスから継承する場合、チェーンの最初の部分のみがその中に含まれます__bases__
Boris

単一の機能のモジュール全体をインポートすることなく、シンプルでクリーン。
テンペローザ

8

Python 3.7では、inspectをインポートする必要はありません。type.mroで結果が得られます。

>>> class A:
...   pass
... 
>>> class B(A):
...   pass
... 
>>> type.mro(B)
[<class '__main__.B'>, <class '__main__.A'>, <class 'object'>]
>>>

Python 3.xでは、すべてのクラスが基本オブジェクトクラスから継承されることに注意してください。


8

Python docによると、class.__mro__属性またはclass.mro()メソッドを使用することもできます。

>>> class A:
...     pass
... 
>>> class B(A):
...     pass
... 
>>> B.__mro__
(<class '__main__.B'>, <class '__main__.A'>, <class 'object'>)
>>> A.__mro__
(<class '__main__.A'>, <class 'object'>)
>>> object.__mro__
(<class 'object'>,)
>>>
>>> B.mro()
[<class '__main__.B'>, <class '__main__.A'>, <class 'object'>]
>>> A.mro()
[<class '__main__.A'>, <class 'object'>]
>>> object.mro()
[<class 'object'>]
>>> A in B.mro()
True

2

Jochenの答えは非常に役に立ち、正しいですが、inspectモジュールの.getmro()メソッドを使用してクラス階層を取得できるため、Pythonの継承階層が次のようであることを強調することも重要です。

例:

class MyClass(YourClass):

継承クラス

  • 子クラス
  • 派生クラス
  • サブクラス

例:

class YourClass(Object):

継承されたクラス

  • 親クラス
  • 基本クラス
  • スーパークラス

あるクラスは別のクラスから継承できます-クラスの属性が継承されます-特に、そのメソッドが継承されます-これは、継承(子)クラスのインスタンスが継承(親)クラスの属性にアクセスできることを意味します

インスタンス->クラス->継承されたクラス

を使用して

import inspect
inspect.getmro(MyClass)

Python内の階層が表示されます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.