วิธีการสืบทอดและการเริ่มต้นใน Python


94

ฉันขอทานงูหลาม ฉันไม่เข้าใจเรื่องมรดกและ__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__()ในการจะได้รับการสืบทอดมาจากNum2Num

เมื่อคลาสกำหนด__init__() วิธีการอินสแตนซ์คลาสจะเรียกใช้__init__()อินสแตนซ์คลาสที่สร้างขึ้นใหม่โดยอัตโนมัติ

ในสถานการณ์ที่สองตั้งแต่คุณกําหนด__init__()ในการNum2ที่คุณต้องชัดเจนโทรหนึ่งในชั้นซุปเปอร์ ( Num) ถ้าคุณต้องการที่จะขยายพฤติกรรมของมัน

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

23
การอ้างอิงของคุณไม่เพียงพอที่จะอธิบายว่าเหตุใดเมื่อไม่ได้กำหนด__init__วิธีการในคลาสที่ได้รับมาจะได้รับการสืบทอด เป็นเพราะ"หากไม่พบแอตทริบิวต์ที่ร้องขอในคลาสการค้นหาจะดูในคลาสพื้นฐาน" (doc)
eyquem

5
ฉันขอโทษ ... โดยพื้นฐานแล้วการสืบทอดทำงานอย่างไร ... ถ้าคุณสืบทอดคลาสคุณจะได้รับแพ็คเกจทั้งหมดดังนั้นทุกอย่างในซูเปอร์คลาสจึงมีอยู่ในคลาสย่อย แต่ถ้าคุณกำหนดวิธีการใหม่มันจะถูกลบล้าง ... นั่นคือสิ่งที่เกิดขึ้นในโค้ดของคุณ
coya

4
@ mario-duarte เหตุผลใดที่จะดีกว่านี้super(Num2, self).__init__(num)?
guival

1
ฉันเพิ่งเปลี่ยนจากโซลูชันที่เสนอในคำตอบนี้ไปใช้superและโปรแกรมของฉันโหลดเร็วขึ้นสองสามวินาที ไม่รู้ว่าทำไม
Guimoute

superควรจะเป็นประโยชน์เมื่อใช้มรดกหลายอย่าง ผลประโยชน์ของมันไม่ชัดเจน
Johann Bzh



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 แม้ว่านี่จะไม่ใช่คำตอบสำหรับคำถาม แต่ก็มีประโยชน์ บางครั้งคำตอบที่คนโพสต์เป็นคำตอบของคำถามที่คนอื่นควรถาม ขอบคุณ!
Glen Thompson
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.