Pythonでsuper(self.__class__, self)は使うな
[追記:2013/11/02]
この記事ではPython2.xを前提としていますが、Python3以降はsuperの引数を省略することができるようになっています。
[/追記]
次のPythonコードを見てください。
class A(object): def method(self): pass class B(A): def method(self): super(self.__class__, self).method() class C(B): def method(self): super(self.__class__, self).method() >>> c = C() >>> c.method()
このコードを実行すると、
RuntimeError: maximum recursion depth exceeded while calling a Python object
すなわち再帰の深さが限界に達したと言われてランタイムエラーが発生します。
C.methodの中のsuperによって渡されたself
オブジェクトは、クラスCのインスタンスです。
よってsuperから呼ばれたB.methodの中ではself.__class__
がCと解釈されて、
super(C, self).method() # => B.methodが呼ばれる
となってしまうのでB.methodがB.methodを呼び、無限再帰になってしまうのです。
これを解消するためにはsuper(B, self).method
のようにクラス名をちゃんと明記するか、A.method
のように直接クラスのメソッドにアクセスします。
また、参考として、こういうハックもあります:
問題点
この問題はあまりメジャーではないのか、super(self.__class__, self)
と書いているコードはたくさん見かけます。しかし、これは非常に大きな問題だと思います。
super(self.__class__, self)
を使っているクラスを継承してsuper(self.__class__, self)
と書いてはいけない。ということを意識してPythonを書いている人がどれだけいるのか?
これといって良い代替案がないことも問題でしょう。「スーパークラスのメソッドを呼ぶこと」と「Aクラスのメソッドを呼ぶこと」は全然意味が違います。それなのにsuperが使いにくいからA.method
と書きなさいというのはいくらなんでもひどすぎではないか?
他に方法があれば教えていただけると嬉しいのですが、いずれにせよsuper(self.__class__, self)
の利用は控えたほうがよさそうです。