ว่าฉันมีสถานการณ์สืบทอดหลาย:
class A(object):
# code for A here
class B(object):
# code for B here
class C(A, B):
def __init__(self):
# What's the right code to write here to ensure
# A.__init__ and B.__init__ get called?
มีสองวิธีทั่วไปเพื่อเขียนเป็นC
's __init__
:
- (แบบเก่า)
ParentClass.__init__(self)
- (ใหม่สไตล์)
super(DerivedClass, self).__init__()
อย่างไรก็ตามในกรณีใดกรณีหนึ่งถ้าคลาสแม่ ( A
และB
) ไม่ปฏิบัติตามแบบแผนเดียวกันรหัสจะทำงานไม่ถูกต้อง (บางคนอาจพลาดหรือถูกเรียกหลายครั้ง)
ดังนั้นวิธีที่ถูกต้องอีกครั้งคืออะไร? มันง่ายที่จะพูดว่า "แค่ทำตามทำตามอย่างใดอย่างหนึ่ง" แต่ถ้าA
หรือB
จากห้องสมุดของบุคคลที่สามแล้วจะเป็นอย่างไร? มีวิธีการที่สามารถตรวจสอบให้แน่ใจว่าผู้สร้างคลาสผู้ปกครองทั้งหมดได้รับการเรียก (และในลำดับที่ถูกต้องและเพียงครั้งเดียว)?
แก้ไข: เพื่อดูสิ่งที่ฉันหมายถึงถ้าฉันทำ:
class A(object):
def __init__(self):
print("Entering A")
super(A, self).__init__()
print("Leaving A")
class B(object):
def __init__(self):
print("Entering B")
super(B, self).__init__()
print("Leaving B")
class C(A, B):
def __init__(self):
print("Entering C")
A.__init__(self)
B.__init__(self)
print("Leaving C")
จากนั้นฉันจะได้รับ:
Entering C
Entering A
Entering B
Leaving B
Leaving A
Entering B
Leaving B
Leaving C
โปรดทราบว่าB
init ถูกเรียกสองครั้ง ถ้าฉันทำ:
class A(object):
def __init__(self):
print("Entering A")
print("Leaving A")
class B(object):
def __init__(self):
print("Entering B")
super(B, self).__init__()
print("Leaving B")
class C(A, B):
def __init__(self):
print("Entering C")
super(C, self).__init__()
print("Leaving C")
จากนั้นฉันจะได้รับ:
Entering C
Entering A
Leaving A
Leaving C
โปรดทราบว่าB
init ไม่เคยถูกเรียก ดังนั้นดูเหมือนว่าเว้นแต่ฉันจะรู้ / ควบคุมผู้เริ่มต้นของชั้นเรียนที่ฉันสืบทอดมาจาก ( A
และB
) ฉันไม่สามารถสร้างทางเลือกที่ปลอดภัยสำหรับชั้นเรียนที่ฉันกำลังเขียน ( C
)