super()
基本クラスのメソッドを呼び出す標準的な方法と見なされるべきではありません。これは Python 3.x でも変わりませんでした。変更された唯一のことは、現在の関数の最初のパラメーターであり、現在定義されているクラスself, cls
である標準ケースで引数を渡す必要がないことです。self
cls
を実際にいつ使用するかという質問に関してsuper()
、私の答えは次のとおりです。super()
私は個人的に、便利な多重継承を避けるようにしています。
編集:私がかつて遭遇した実生活の例:run()
メソッドを定義するいくつかのクラスがあり、そのうちのいくつかには基本クラスがありました。以前super()
は継承されたコンストラクターを呼び出していましたが、単一の継承のみを使用していたため、それが問題になるとは思いませんでした。
class A(object):
def __init__(self, i):
self.i = i
def run(self, value):
return self.i * value
class B(A):
def __init__(self, i, j):
super(B, self).__init__(i)
self.j = j
def run(self, value):
return super(B, self).run(value) + self.j
これらのクラスがいくつかあり、すべてが個別のコンストラクター プロトタイプを持ち、run()
.
ここで、これらすべてのクラスにロギングなどの機能を追加したいと考えました。追加の機能では、これらすべてのクラスで追加のメソッドを定義する必要がありましたinfo()
。元のクラスに侵入したくはありませんでしたが、元のクラスから継承する 2 番目のクラス セットを定義し、info()
メソッドを追加して、実際のログを提供する mix-in から継承しました。今、super()
コンストラクターで使用できなくなったため、直接呼び出しを使用しました。
class Logger(object):
def __init__(self, name):
self.name = name
def run_logged(self, value):
print "Running", self.name, "with info", self.info()
return self.run(value)
class BLogged(B, Logger):
def __init__(self, i, j):
B.__init__(self, i, j)
Logger.__init__("B")
def info(self):
return 42
ここで物事は機能しなくなります。基本クラスのコンストラクターでのsuper()
呼び出しが突然 を呼び出しLogger.__init__()
、BLogged
それについて何もできません。実際には、super()
呼び出しB
自体を削除する以外に、これを機能させる方法はありません。
[別の編集:ここと他の回答の下のすべてのコメントから判断すると、私は自分の主張をしていないようです。を使用してこのコードを機能させる方法は次のsuper()
とおりです。
class A(object):
def __init__(self, i, **kwargs):
super(A, self).__init__(**kwargs)
self.i = i
def run(self, value):
return self.i * value
class B(A):
def __init__(self, j, **kwargs):
super(B, self).__init__(**kwargs)
self.j = j
def run(self, value):
return super(B, self).run(value) + self.j
class Logger(object):
def __init__(self, name, **kwargs):
super(Logger,self).__init__(**kwargs)
self.name = name
def run_logged(self, value):
print "Running", self.name, "with info", self.info()
return self.run(value)
class BLogged(B, Logger):
def __init__(self, **kwargs):
super(BLogged, self).__init__(name="B", **kwargs)
def info(self):
return 42
b = BLogged(i=3, j=4)
これを明示的なスーパークラス呼び出しの使用と比較してください。好みのバージョンを決定します。]
super()
これと同様の話が、基本クラスのメソッドを呼び出す標準的な方法と見なされるべきではないと私が考える理由です。super()
壊れているわけではありません。