33

Python コードがある場合

class A():
    pass
class B():
    pass
class C(A, B):
    pass

と私はクラスを持っていますC、それを反復処理する方法はありAますBか? 擬似コードのようなもの:

>>> magicGetSuperClasses(C)
(<type 'A'>, <type 'B'>)

1つの解決策は、モジュールと機能を検査することです。getclasstree

def magicGetSuperClasses(cls):
    return [o[0] for o in inspect.getclasstree([cls]) if type(o[0]) == type]

しかし、これは目標を達成するための「Pythonian」の方法ですか?

4

4 に答える 4

37

C.__bases__スーパークラスの配列であるため、次のように仮想関数を実装できます。

def magicGetSuperClasses(cls):
  return cls.__bases__

cls.__bases__しかし、ほとんどの場合、直接参照する方が簡単だと思います。

于 2008-08-25T09:22:22.147 に答える
11

@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 は一般的に簡単でクールです。:)

于 2008-08-29T19:30:31.763 に答える
2

super() が使用できるクラスを呼び出す順序を知る必要がある場合は、使用するC.__mro__必要がないinspectためです。

于 2009-02-16T16:38:14.167 に答える