2014/01/23

Pythonの super() 関数の使い方

Pythonでスーパークラスのインスタンスメソッドを呼び出すときに使える super() 関数の使い方をご紹介します。

まずは例から。
class Dog(object):
    def __init__(self, name):
       self.name = name

class UltraDog(Dog):
    def __init__(self, name, type):
        super(UltraDog, self).__init__(name)
        self.type = type

ud1 = UltraDog("taro", "akita")
print(ud1.name)

ここでは、サブクラスのインスタンスメソッドの中で、スーパークラスのインスタンスメソッドを呼び出しています。具体的には、Dog のサブクラス UltraDog の __init__ メソッドの中でスーパークラスである Dog の __init__ メソッドを呼び出します。そのときに super() 関数を使っています。

意図としては、スーパークラスの __init__ メソッドの中に name を初期化する処理がすでに存在するので、それをサブクラス UltraDog の中でも再利用しよう、というものです。

super() 関数の使い方は super(クラス名, self).メソッド名 です。この形で呼び出されたスーパークラスのインスタンスメソッドは self をレシーバとして実行される形となります。

書き方としてちょっと気持ち悪い気もしますが、「Explicit is better than implicit」というところを優先した感じでしょうか。

1点、使う際の注意点としては、親クラスの Dog の方で object クラスを継承するのを忘れないことです。これを忘れて
class Dog:
   ...
という形で宣言してしまうと super() がきちんと動いてくれず「TypeError: must be type, not classobj」と怒られてしまいます。

ちなみにPython 3では super() の引数を省略することができて
super().__init__(name)
と書くことができます。


参考
inheritance - Understanding Python super() and init methods - Stack Overflow
python super() raises TypeError ! Why? - Stack Overflow
python - super() fails with error: TypeError "argument 1 must be type, not classobj" - Stack Overflow

0 件のコメント: