web-dev-qa-db-ja.com

Python super()引数:なぜsuper(obj)ではないのですか?

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)と入力するだけでいいショートカットになると思います。

31
Gabriel

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で時々必要になる場合がありますが、異常な状況では常により難解な使用法でした。

39
BrenBarn

短い答えを試してみてください:

_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()も認識していません。

2
kxr