Pythonの継承とinitメソッド


94

私はPythonの初心者です。相続がわからないと__init__()

class Num:
    def __init__(self,num):
        self.n1 = num

class Num2(Num):
    def show(self):
        print self.n1

mynumber = Num2(8)
mynumber.show()

結果: 8

これで結構です。しかし、私は交換するNum2

class Num2(Num):
    def __init__(self,num):
        self.n2 = num*2
    def show(self):
        print self.n1,self.n2

結果: Error. Num2 has no attribute "n1".

この場合、どのようにNum2アクセスできますn1か?

回答:


148

最初の状況でNum2は、はクラスNumを拡張していますが、で指定さ__init__()れた特別なメソッドを再定義していないため、からNum2継承されNumます。

クラスが__init__() メソッドを定義すると、クラスのインスタンス化__init__()により、新しく作成されたクラスインスタンスが自動的に呼び出されます。

2番目の状況では、で再定義__init__()Num2ているので、Numその動作を拡張する場合は、スーパークラス()の1つを明示的に呼び出す必要があります。

class Num2(Num):
    def __init__(self,num):
        Num.__init__(self,num)
        self.n2 = num*2

23
__init__派生クラスでメソッドを定義しないと、メソッドが継承される理由を説明するには、引用だけでは不十分です。これは、「要求された属性がクラスで見つからない場合、検索は基本クラスの検索に進む」ためです。(doc)
eyquem 2011

5
申し訳ありません...基本的に継承の仕組みです...クラスを継承すると、パッケージ全体が取得されるため、スーパークラスのすべてがサブクラスに存在します。しかし、メソッドを再定義すると、メソッドはオーバーライドされます...それがコードの内容です。
coya 2017

4
@ mario-duarteこれがより良い理由はsuper(Num2, self).__init__(num)何ですか?
guival 2018年

1
この回答で提案されたソリューションからを使用するように切り替えたところsuper、プログラムの読み込みが数秒速くなりました。理由はわかりません。
Guimoute

super多重継承を使用するときに役立つはずです。単一継承の場合、その利点は明らかではありません。
Johann Bzh


4

を呼び出さないためNum.__init__、フィールド「n1」は作成されません。それを呼ぶと、そこにあります。


3

次のようなNum2クラスの簡単な変更:

super().__init__(num) 

python3で動作します。

class Num:
        def __init__(self,num):
                self.n1 = num

class Num2(Num):
        def __init__(self,num):
                super().__init__(num)
                self.n2 = num*2
        def show(self):
                print (self.n1,self.n2)

mynumber = Num2(8)
mynumber.show()

1
これが私がstackoverflowが大好きな理由です。これは質問に対する答えではありませんが、役に立ちます。時々、人々が投稿する答えは、人々が尋ねるべきだった質問への答えです。ありがとうございました!
グレントンプソン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.