Python(2.7.xまたは3.x)でsuper()をいつどのように正しく使用するかを理解しようとしています
>>> help(super)
で、インタプリタはそれを呼び出す方法を教えてくれます。
_class super(object)
| super(type) -> unbound super object
| super(type, obj) -> bound super object; requires isinstance(obj, type)
| super(type, type2) -> bound super object; requires issubclass(type2, type)
_
Python3.xでは、クラス定義内でsuper()を使用できるようになったことは理解していますが、super(obj)
が使用できない理由がわかりません。または、クラス定義内のsuper(self)
。
理由があるに違いないのはわかっていますが、見つかりません。私にとって、これらの行はsuper(obj.__class__, obj)
またはsuper(self.__class__, self)
と同等であり、正しく機能しますか?
Python 3.xでも、super(obj)
と入力するだけでいいショートカットになると思います。
2つの引数の形式は、Python 2でのみ必要です。理由は、self.__class__
が常に継承ツリーの「leaf」クラス、つまりオブジェクトの最も具体的なクラスを参照するためです。 -ただし、super
を呼び出すときは、現在呼び出されている実装を指定する必要があります。これにより、継承ツリーで次の実装を呼び出すことができます。
あなたが持っているとしましょう:
class A(object):
def foo(self):
pass
class B(A):
def foo(self):
super(self.__class__, self).foo()
class C(B):
def foo(self):
super(self.__class__, self).foo()
c = C()
c.__class__
は常にC
であることに注意してください。 c.foo()
を呼び出すとどうなるか考えてみましょう。
Cのメソッドでsuper(self.__class__, self)
を呼び出すと、super(C, self)
を呼び出すのと同じようになります。つまり、「Cによって継承されたこのメソッドのバージョンを呼び出す」ということです。それはB.foo
を呼び出しますが、これは問題ありません。ただし、Bからsuper(self.__class__, self)
を呼び出す場合は、super(C, self)
を呼び出すのと同じです。これは、同じself
であるため、self.__class__
はC
のままです。その結果、Bでの呼び出しは再びB.foo
を呼び出し、無限再帰が発生します。
もちろん、本当に必要なのはsuper(classThatDefinedTheImplementationThatIsCurrentlyExecuting, self)
を呼び出せるようにすることであり、それが事実上Python 3 super()
が行うことです。
Python 3では、super().foo()
を実行するだけで、正しいことを実行できます。super(self)
がショートカットであるとはどういう意味か、私にはわかりません。 Python 2、上記の理由で機能しません。Python 3では、プレーンを使用できるため、「ショートカット」になります。代わりにsuper()
。
super(type)
とsuper(type1, type2)
の使用は、Python 3で時々必要になる場合がありますが、異常な状況では常により難解な使用法でした。
短い答えを試してみてください:
_self.__class__
_は常に、オブジェクトインスタンスの実際の(「サブモスト」)クラスです。関数を実装する必要なクラスである必要はありません。
super(self.__class__, self)
をsuper(__class__, self)
に置き換えると、Python 3は、Python 3が提供するため、メソッド定義内にあります。実装クラスのマジックセル変数___class__
_。
そして、引数がゼロのsuper()
は、すでにPython 3のsuper(__class__, self)
のショートカットです。 PEP3135 を参照してください。
Python 2は、___class__
_も引数なしのショートカットsuper()
も認識していません。