Python'da kalıtım ve başlangıç ​​yöntemi


94

Python'a başladım. Kalıtımı anlayamıyorum ve __init__().

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

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

mynumber = Num2(8)
mynumber.show()

SONUÇ: 8

Tamamdır. Ama yerini Num2ile

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

SONUÇ: Error. Num2 has no attribute "n1".

Bu durumda nasıl Num2erişilir n1?

Yanıtlar:


148

İlk durumda, Num2sınıfı genişletmek ve içinde Numadı geçen özel yöntemi yeniden tanımlamadığınız için , sınıftan miras alınır .__init__()Num2Num

Bir sınıf bir __init__() yöntemi tanımladığında , sınıf somutlaştırması __init__()yeni oluşturulan sınıf örneğini otomatik olarak çağırır .

İkinci durumda, yeniden tanımlıyor çünkü __init__()içinde Num2açıkça süper sınıfı (tane çağırmanız gerekir Num) onun davranışlarını uzatmak istiyorum.

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

23
Alıntınız, __init__türetilmiş bir sınıfta bir yöntem tanımlanmadığında neden miras alındığını açıklamak için yeterli değildir . Bunun nedeni, "sınıfta istenen bir öznitelik bulunmazsa, arama temel sınıfa bakmaya devam eder." (doc)
eyquem

5
Üzgünüm ... kalıtım temelde böyle çalışır ... bir sınıfı miras alırsanız, tüm paketi alırsınız, yani üst sınıftaki her şey alt sınıfta bulunur. Ancak, bir yöntemi yeniden tanımlarsanız, geçersiz kılınır ... kodunuzda olan şey budur.
coya

4
@ mario-duarte bunun daha iyi olmasının herhangi bir nedeni var super(Num2, self).__init__(num)mı?
2018,

1
Bu cevapta önerilen çözümden kullanmaya geçtim superve programım şimdi birkaç saniye daha hızlı yükleniyor. Neden olduğuna dair hiçbir fikrim yok.
Guimoute

superçoklu kalıtım kullanıldığında yardımcı olması gerekir. Tek bir miras için faydaları açık değildir.
Johann Bzh



3

Num2 sınıfında şöyle basit bir değişiklik:

super().__init__(num) 

Python3'te çalışır.

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
Bu yüzden stackoverflow'u seviyorum. Sorunun cevabı bu olmasa da faydalıdır. Bazen insanların gönderdiği yanıtlar, insanların sorması gereken sorunun yanıtlarıdır. Teşekkür ederim!
Glen Thompson
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.