Pythonクラスの親を取得するにはどうすればよいですか?


回答:


233

次の属性を使用します。

cls.__bases__

ドキュメントから:

クラスオブジェクトの基本クラスのタプル。

例:

>>> str.__bases__
(<type 'basestring'>,)

もう一つの例:

>>> class A(object):
...   pass
... 
>>> class B(object):
...   pass
... 
>>> class C(A, B):
...   pass
... 
>>> C.__bases__
(<class '__main__.A'>, <class '__main__.B'>)

1
インスタンス化されたオブジェクトのベースを取得するには、type(C()).__bases__以下でさらに説明するようにします
citynorman

106

直接の祖先だけでなく、すべての祖先が必要な場合は、inspect.getmroを使用します

import inspect
print inspect.getmro(cls)

便利なことに、これはすべての祖先クラスを「メソッド解決順序」、つまり、メソッド(または実際には他の属性)を解決するときに祖先がチェックされる順序を提供します-メソッドと他の属性は同じ名前空間にあります結局のところ、Pythonでは;-)。


34
cls.__mro__(少なくともPython 3.5では)を使用することもできます
naught101

@ naught101、plzはそれを完全な答えに変えます。私はそれをほとんど見逃していたので、他の人もたくさんいると思います。
Shihab Shahriar Khan 2018

14

新しいスタイルのクラスには、メソッド解決順序で親クラスのリストを返す呼び出し可能なmroメソッドがあります。


新しいスタイルのクラスとは何ですか?これはDjangoモデルで使用できるようですが、単純に継承したものは何もobject応答しないようですmro
Brian Kung

1
オブジェクトを考慮するとx、我々はコールとメソッド解決順得ることができる type(x).mro() ならば、我々は考えることができxているClassX:との基本クラスとして ClassX in type(x).mro()
648trindade

13

最速の方法は、すべての親を見て、と順番は、ちょうどに建て使用します__mro__

すなわち repr(YOUR_CLASS.__mro__)


>>>
>>>
>>> import getpass
>>> getpass.GetPassWarning.__mro__

出力、順番どおり


(<class 'getpass.GetPassWarning'>, <type 'exceptions.UserWarning'>,
<type 'exceptions.Warning'>, <type 'exceptions.Exception'>, 
<type 'exceptions.BaseException'>, <type 'object'>)
>>>

そこにあります。現在の「最良の」答えは182票です(これを入力しているため)。これは、クラスが2つ以上の親を拡張する場合は言うまでもなく、一度に1つのクラスのベースを調べる複雑なforループよりもはるかに単純です。クラス。インポートして使用するinspectと、スコープが不必要にクラウド化されます。正直に言うと、ビルトインを使用するだけでは知らないのは残念

これがお役に立てば幸いです。


@John Smith stackoverflow.com/users/139885/john-smith、私はあなたがこの答えを見ることを望みます。よろしければ、賛成票でお知らせください。
PyTis

1
実際、github.com / python / cpython / blob /…で確認できるように、オブジェクトをinspect.getmro呼び出すだけです。を使用 すると、よりクリーンで読みやすいコードが生成されます。関数呼び出しをスキップする方が確かに高速ですが。__mro__getmro
tna0y

9

親を取得したいだけの場合はベースを使用し、__mro__(@ naught101で指摘されているように)メソッド解決の順序を取得するために使用します(これにより、initが実行された順序がわかります)。

ベース(および既存のオブジェクトのクラスを最初に取得):

>>> some_object = "some_text"
>>> some_object.__class__.__bases__
(object,)

最近のPythonバージョンのmroの場合:

>>> some_object = "some_text"
>>> some_object.__class__.__mro__
(str, object)

もちろん、すでにクラス定義がある場合は__mro__、それを直接呼び出すことができます。

>>> class A(): pass
>>> A.__mro__
(__main__.A, object)

3

すべてが確実に呼び出されるようにしたい場合はsuper、すべてのレベルで使用してください。


superを使用すると、とにかくすべてのレベルで使用する必要があるため、明示的に使用することを文書化する必要があります。また、スーパーがすべてのクラスで機能するわけではないことを知りたいかもしれません...
DasIch
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.