Nói rằng tôi có một kịch bản thừa kế:
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ó hai cách tiếp cận điển hình để viết C
's __init__
:
- (phong cách cũ)
ParentClass.__init__(self)
- (kiểu mới hơn)
super(DerivedClass, self).__init__()
Tuy nhiên, trong cả hai trường hợp, nếu các lớp cha ( A
và B
) không tuân theo cùng một quy ước, thì mã sẽ không hoạt động chính xác (một số có thể bị bỏ qua hoặc được gọi nhiều lần).
Vì vậy, những gì đúng cách một lần nữa? Thật dễ dàng để nói "chỉ cần nhất quán, theo dõi cái này hay cái khác", nhưng nếu A
hoặc B
là từ thư viện của bên thứ 3 thì sao? Có một cách tiếp cận nào có thể đảm bảo rằng tất cả các hàm tạo của lớp cha mẹ được gọi (và theo đúng thứ tự và chỉ một lần) không?
Chỉnh sửa: để xem ý tôi là gì, nếu tôi làm:
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")
Sau đó tôi nhận được:
Entering C
Entering A
Entering B
Leaving B
Leaving A
Entering B
Leaving B
Leaving C
Lưu ý rằng B
init của được gọi hai lần. Nếu tôi làm:
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")
Sau đó tôi nhận được:
Entering C
Entering A
Leaving A
Leaving C
Lưu ý rằng B
init không bao giờ được gọi. Vì vậy, có vẻ như trừ khi tôi biết / kiểm soát các init mà tôi thừa kế từ ( A
và B
) tôi không thể đưa ra lựa chọn an toàn cho lớp tôi đang viết ( C
).