Khi lập trình hướng đối tượng với Python, ta thường bắt gặp các câu lệnh như
class Parent:
def self_intro[self]:
print["This is parent class"]
def parent_method[self]:
print["This is parent method"]
class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
Parent.self_intro[self]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
0 hoặc class Parent:
def self_intro[self]:
print["This is parent class"]
def parent_method[self]:
print["This is parent method"]
class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
Parent.self_intro[self]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
1 nhất là khi đọc doc của các thư viện có các lớp kế thừa nhiều lần. Bài viết hôm nay của mình sẽ hướng đến việc giới thiệu hàm class Parent:
def self_intro[self]:
print["This is parent class"]
def parent_method[self]:
print["This is parent method"]
class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
Parent.self_intro[self]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
2 và các trường hợp sử dụng nó.1. Kế thừa trong Python
Để hiểu rõ hơn về vai trò của
class Parent:
def self_intro[self]:
print["This is parent class"]
def parent_method[self]:
print["This is parent method"]
class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
Parent.self_intro[self]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
2. Mình sẽ bắt đầu với trường hợp không sử dụng class Parent:
def self_intro[self]:
print["This is parent class"]
def parent_method[self]:
print["This is parent method"]
class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
Parent.self_intro[self]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
2 trong kế thừa trước. Cho lớp cha class Parent:
def self_intro[self]:
print["This is parent class"]
def parent_method[self]:
print["This is parent method"]
class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
Parent.self_intro[self]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
5 và được kế thừa bởi lớp con class Parent:
def self_intro[self]:
print["This is parent class"]
def parent_method[self]:
print["This is parent method"]
class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
Parent.self_intro[self]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
6, khi đó lớp class Parent:
def self_intro[self]:
print["This is parent class"]
def parent_method[self]:
print["This is parent method"]
class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
Parent.self_intro[self]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
7 có thể gọi các phương thức hoặc thuộc tính từ lớp cha.class Parent:
def self_intro[self]:
print["This is parent class"]
def parent_method[self]:
print["This is parent method"]
class Children[Parent]:
def self_intro[self]:
print["This is children class"]
c = Children[]
c.parent_method[]
# >>> This is parent method
Tuy nhiên, sẽ xảy ra trường hợp
class Parent:
def self_intro[self]:
print["This is parent class"]
def parent_method[self]:
print["This is parent method"]
class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
Parent.self_intro[self]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
7 và class Parent:
def self_intro[self]:
print["This is parent class"]
def parent_method[self]:
print["This is parent method"]
class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
Parent.self_intro[self]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
5 có phương thức trùng tên với nhau là class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
super[].self_intro[]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
0 và ta cần gọi phương thức class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
super[].self_intro[]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
0 của class Parent:
def self_intro[self]:
print["This is parent class"]
def parent_method[self]:
print["This is parent method"]
class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
Parent.self_intro[self]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
5 bên trong phương thức class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
super[].self_intro[]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
3 của class Parent:
def self_intro[self]:
print["This is parent class"]
def parent_method[self]:
print["This is parent method"]
class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
Parent.self_intro[self]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
7. Trường hợp này vẫn có thể được giải quyết mà không cần dùng đến class Parent:
def self_intro[self]:
print["This is parent class"]
def parent_method[self]:
print["This is parent method"]
class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
Parent.self_intro[self]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
2 bằng cách gọi trực tiếp class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
super[].self_intro[]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
6 bên trong class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
super[].self_intro[]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
7class Parent:
def self_intro[self]:
print["This is parent class"]
def parent_method[self]:
print["This is parent method"]
class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
Parent.self_intro[self]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
Nhiều bạn đã biết về bound method, unbound method có thể sẽ thắc mắc tại sao lại sử dụng tham số
8 cho phương thứcclass Children[Parent]: def self_intro[self]: print["This is children class"] def family_intro[self]: self.self_intro[] # Same as Children.self_intro[self] super[].self_intro[] c = Children[] c.family_intro[] # >>> This is children class # >>> This is parent class
0 dù hàm này không sử dụng thuộc tính hay phương thức củaclass Children[Parent]: def self_intro[self]: print["This is children class"] def family_intro[self]: self.self_intro[] # Same as Children.self_intro[self] super[].self_intro[] c = Children[] c.family_intro[] # >>> This is children class # >>> This is parent class
8. Vì mình muốn tập trung vào việc giới thiệu phương pháp kế thừa nên đã viết đơn giản hơn thay vì thêm các decorator và thay đổi cách gọi hàm. Bạn nào có nhu cầu biết thêm về bound method, unbound method có thể tham khảo tại đâyclass Children[Parent]: def self_intro[self]: print["This is children class"] def family_intro[self]: self.self_intro[] # Same as Children.self_intro[self] super[].self_intro[] c = Children[] c.family_intro[] # >>> This is children class # >>> This is parent class
Chúng ta cũng có thể giải quyết trường hợp này bằng
class Parent:
def self_intro[self]:
print["This is parent class"]
def parent_method[self]:
print["This is parent method"]
class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
Parent.self_intro[self]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
2 thay vì gọi trực tiếpclass Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
super[].self_intro[]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
Hàm
class Parent:
def self_intro[self]:
print["This is parent class"]
def parent_method[self]:
print["This is parent method"]
class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
Parent.self_intro[self]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
2 lúc này sẽ trả về một đối tượng thuộc lớp kế thừa từ class Parent:
def self_intro[self]:
print["This is parent class"]
def parent_method[self]:
print["This is parent method"]
class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
Parent.self_intro[self]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
7 lúc này là class Parent:
def self_intro[self]:
print["This is parent class"]
def parent_method[self]:
print["This is parent method"]
class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
Parent.self_intro[self]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
5 và gọi class Parent:
pass
class Children[Parent]:
pass
Children.mro[]
# >>> [__main__.Children, __main__.Parent, object]
5. Khác với cách gọi trực tiếp, class Parent:
def self_intro[self]:
print["This is parent class"]
def parent_method[self]:
print["This is parent method"]
class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
Parent.self_intro[self]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
2 không cần viết lại tên lớp class Parent:
def self_intro[self]:
print["This is parent class"]
def parent_method[self]:
print["This is parent method"]
class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
Parent.self_intro[self]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
5 khi gọi hàm, việc này sẽ giúp tránh bị các lỗi chính tả hoặc bạn có nhu cầu đổi tên lớp cha hoặc kế thừa từ lớp khác. Nhưng đấy vẫn chưa phải là tất cả điểm mạnh của class Parent:
def self_intro[self]:
print["This is parent class"]
def parent_method[self]:
print["This is parent method"]
class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
Parent.self_intro[self]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
2. class Parent:
def self_intro[self]:
print["This is parent class"]
def parent_method[self]:
print["This is parent method"]
class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
Parent.self_intro[self]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
2 được sử dụng linh hoạt trong các trường hợp đa kế thừa đặc biệt là Diamond Problem mà mình sẽ giới thiệu sau đây. Trước tiên chúng ta cần phải hiểu rõ một vài khái niệm và các tham số của class Parent:
def self_intro[self]:
print["This is parent class"]
def parent_method[self]:
print["This is parent method"]
class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
Parent.self_intro[self]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
2Nhưng đấy vẫn chưa phải là tất cả điểm mạnh của
class Parent:
def self_intro[self]:
print["This is parent class"]
def parent_method[self]:
print["This is parent method"]
class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
Parent.self_intro[self]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
2. class Parent:
def self_intro[self]:
print["This is parent class"]
def parent_method[self]:
print["This is parent method"]
class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
Parent.self_intro[self]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
2 được sử dụng linh hoạt trong các trường hợp đa kế thừa đặc biệt là Diamond Problem mà mình sẽ giới thiệu sau đây. Trước tiên
chúng ta cần phải hiểu rõ một vài khái niệm và các tham số của class Parent:
def self_intro[self]:
print["This is parent class"]
def parent_method[self]:
print["This is parent method"]
class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
Parent.self_intro[self]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
22. Method resolution order [MRO]
MRO có thể hiểu đơn giản là trình tự kế thừa của lớp. MRO của một lớp có thể được truy xuất bằng phương thức
class Grandparent:
def call_method[self]:
print["This is Grandparent method"]
class Parent[Grandparent]:
def call_method[self]:
print["This is Parent method"]
class Children[Parent]:
def call_method[self]:
# call call_method of GrandParent
# class instead of Parent class
super[Parent, self].call_method[]
c = Children[]
c.call_method[]
# >>> This is Grandparent method
1 MRO sẽ được tạo để đảm bảo các lớp chỉ được liệt kê một lần và các lớp con phải được gọi trước lớp cha. Nếu bạn muốn tìm hiểu thêm về thuật toán tạo MRO của Python thì tham khảo tại đâyMRO sẽ được tạo để đảm bảo các lớp chỉ được liệt kê một lần và các lớp con phải được gọi trước lớp cha. Nếu bạn muốn tìm hiểu thêm về thuật toán tạo MRO của Python thì tham khảo tại đây
class Parent:
pass
class Children[Parent]:
pass
Children.mro[]
# >>> [__main__.Children, __main__.Parent, object]
Khi sử dụng một phương thức với đối tượng thuộc lớp Children, chương trình sẽ tìm kiếm phương thức dựa trên thứ tự MRO như trên, tức là bắt đầu từ Children, nếu không có thì sẽ tìm đến Parent và sau cùng là object [base class mặc định cho mọi loại dữ liệu Python]
3. Tham số của hàm super[]
Hàm
class Grandparent:
def call_method[self]:
print["This is Grandparent method"]
class Parent[Grandparent]:
def call_method[self]:
print["This is Parent method"]
class Children[Parent]:
def call_method[self]:
# call call_method of GrandParent
# class instead of Parent class
super[Parent, self].call_method[]
c = Children[]
c.call_method[]
# >>> This is Grandparent method
2 sẽ nhận vào hai tham số class Grandparent:
def call_method[self]:
print["This is Grandparent method"]
class Parent[Grandparent]:
def call_method[self]:
print["This is Parent method"]
class Children[Parent]:
def call_method[self]:
# call call_method of GrandParent
# class instead of Parent class
super[Parent, self].call_method[]
c = Children[]
c.call_method[]
# >>> This is Grandparent method
3 và class Grandparent:
def call_method[self]:
print["This is Grandparent method"]
class Parent[Grandparent]:
def call_method[self]:
print["This is Parent method"]
class Children[Parent]:
def call_method[self]:
# call call_method of GrandParent
# class instead of Parent class
super[Parent, self].call_method[]
c = Children[]
c.call_method[]
# >>> This is Grandparent method
4:
3 sẽ nhận giá trị kiểu lớp để khi tìm kiếm phương thức hoặc thuộc tính, chương trình sẽ tìm các lớp cha sauclass Grandparent: def call_method[self]: print["This is Grandparent method"] class Parent[Grandparent]: def call_method[self]: print["This is Parent method"] class Children[Parent]: def call_method[self]: # call call_method of GrandParent # class instead of Parent class super[Parent, self].call_method[] c = Children[] c.call_method[] # >>> This is Grandparent method
3 trong MRO của lớp. Dựa vàoclass Grandparent: def call_method[self]: print["This is Grandparent method"] class Parent[Grandparent]: def call_method[self]: print["This is Parent method"] class Children[Parent]: def call_method[self]: # call call_method of GrandParent # class instead of Parent class super[Parent, self].call_method[] c = Children[] c.call_method[] # >>> This is Grandparent method
3 ta có thể quyết định phương thức cần gọi được cài đặt trong lớp cha hoặc lớp ông nội.class Grandparent: def call_method[self]: print["This is Grandparent method"] class Parent[Grandparent]: def call_method[self]: print["This is Parent method"] class Children[Parent]: def call_method[self]: # call call_method of GrandParent # class instead of Parent class super[Parent, self].call_method[] c = Children[] c.call_method[] # >>> This is Grandparent method
4 sẽ nhận vào một đối tượng để ràng buộc [bound] với phương thức hoặc thuộc tính được gọi bởiclass Grandparent: def call_method[self]: print["This is Grandparent method"] class Parent[Grandparent]: def call_method[self]: print["This is Parent method"] class Children[Parent]: def call_method[self]: # call call_method of GrandParent # class instead of Parent class super[Parent, self].call_method[] c = Children[] c.call_method[] # >>> This is Grandparent method
2.class Parent: def self_intro[self]: print["This is parent class"] def parent_method[self]: print["This is parent method"] class Children[Parent]: def self_intro[self]: print["This is children class"] def family_intro[self]: self.self_intro[] # Same as Children.self_intro[self] Parent.self_intro[self] c = Children[] c.family_intro[] # >>> This is children class # >>> This is parent class
Để dễ hình dung,
class Grandparent:
def call_method[self]:
print["This is Grandparent method"]
class ParentA[Grandparent]:
def call_method[self]:
print["This is ParentA method"]
class ParentB[Grandparent]:
def call_method[self]:
print["This is ParentB method"]
class Children[ParentA, ParentB]:
def say_name[self]:
super[].say_name[]
c = Children[]
print[Children.mro[]]
# >>> [, ,
# , , ]
c.call_method[]
# >>> This is ParentA method
0 có thể hiểu là class Grandparent:
def call_method[self]:
print["This is Grandparent method"]
class ParentA[Grandparent]:
def call_method[self]:
print["This is ParentA method"]
class ParentB[Grandparent]:
def call_method[self]:
print["This is ParentB method"]
class Children[ParentA, ParentB]:
def say_name[self]:
super[].say_name[]
c = Children[]
print[Children.mro[]]
# >>> [, ,
# , , ]
c.call_method[]
# >>> This is ParentA method
1 với phương thức class Grandparent:
def call_method[self]:
print["This is Grandparent method"]
class ParentA[Grandparent]:
def call_method[self]:
print["This is ParentA method"]
class ParentB[Grandparent]:
def call_method[self]:
print["This is ParentB method"]
class Children[ParentA, ParentB]:
def say_name[self]:
super[].say_name[]
c = Children[]
print[Children.mro[]]
# >>> [, ,
# , , ]
c.call_method[]
# >>> This is ParentA method
2 được cài đặt trong lớp cha của class Grandparent:
def call_method[self]:
print["This is Grandparent method"]
class Parent[Grandparent]:
def call_method[self]:
print["This is Parent method"]
class Children[Parent]:
def call_method[self]:
# call call_method of GrandParent
# class instead of Parent class
super[Parent, self].call_method[]
c = Children[]
c.call_method[]
# >>> This is Grandparent method
3.Xét ví dụ trên, hàm
class Parent:
def self_intro[self]:
print["This is parent class"]
def parent_method[self]:
print["This is parent method"]
class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
Parent.self_intro[self]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
2 được gọi trong lớp class Parent:
def self_intro[self]:
print["This is parent class"]
def parent_method[self]:
print["This is parent method"]
class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
Parent.self_intro[self]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
7 sẽ có giá trị tham số mặc định là class Grandparent:
def call_method[self]:
print["This is Grandparent method"]
class ParentA[Grandparent]:
def call_method[self]:
print["This is ParentA method"]
class ParentB[Grandparent]:
def call_method[self]:
print["This is ParentB method"]
class Children[ParentA, ParentB]:
def say_name[self]:
super[].say_name[]
c = Children[]
print[Children.mro[]]
# >>> [, ,
# , , ]
c.call_method[]
# >>> This is ParentA method
6.class Grandparent:
def call_method[self]:
print["This is Grandparent method"]
class Parent[Grandparent]:
def call_method[self]:
print["This is Parent method"]
class Children[Parent]:
def call_method[self]:
# call call_method of GrandParent
# class instead of Parent class
super[Parent, self].call_method[]
c = Children[]
c.call_method[]
# >>> This is Grandparent method
Ngoài ra
class Grandparent:
def call_method[self]:
print["This is Grandparent method"]
class Parent[Grandparent]:
def call_method[self]:
print["This is Parent method"]
class Children[Parent]:
def call_method[self]:
# call call_method of GrandParent
# class instead of Parent class
super[Parent, self].call_method[]
c = Children[]
c.call_method[]
# >>> This is Grandparent method
3 và class Grandparent:
def call_method[self]:
print["This is Grandparent method"]
class Parent[Grandparent]:
def call_method[self]:
print["This is Parent method"]
class Children[Parent]:
def call_method[self]:
# call call_method of GrandParent
# class instead of Parent class
super[Parent, self].call_method[]
c = Children[]
c.call_method[]
# >>> This is Grandparent method
4 còn có một số ràng buộc để chương trình chạy không bị lỗi mà bạn có thể tham khảo tại doc của class Parent:
def self_intro[self]:
print["This is parent class"]
def parent_method[self]:
print["This is parent method"]
class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
Parent.self_intro[self]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
2Lưu ý: Nếu trong
0 của lớpclass Grandparent: def __init__[self]: print["Grandparent Init"] class ParentA[Grandparent]: def __init__[self]: print["ParentA Init"] GrandParent.__init__[self] class ParentB[Grandparent]: def __init__[self]: print["ParentB Init"] GrandParent.__init__[self] class Children[ParentA, ParentB]: def __init__[self]: print["Children Init"] ParentA.__init__[self] ParentB.__init__[self] Children[] # >>> Children Init # >>> ParentA Init # >>> Grandparent Init # >>> ParentB Init # >>> Grandparent Init
1 gọi tiếpclass Grandparent: def __init__[self]: print["Grandparent Init"] class ParentA[Grandparent]: def __init__[self]: print["ParentA Init"] GrandParent.__init__[self] class ParentB[Grandparent]: def __init__[self]: print["ParentB Init"] GrandParent.__init__[self] class Children[ParentA, ParentB]: def __init__[self]: print["Children Init"] ParentA.__init__[self] ParentB.__init__[self] Children[] # >>> Children Init # >>> ParentA Init # >>> Grandparent Init # >>> ParentB Init # >>> Grandparent Init
2. Hàm sẽ tìmclass Grandparent: def __init__[self]: print["Grandparent Init"] class ParentA[Grandparent]: def __init__[self]: print["ParentA Init"] GrandParent.__init__[self] class ParentB[Grandparent]: def __init__[self]: print["ParentB Init"] GrandParent.__init__[self] class Children[ParentA, ParentB]: def __init__[self]: print["Children Init"] ParentA.__init__[self] ParentB.__init__[self] Children[] # >>> Children Init # >>> ParentA Init # >>> Grandparent Init # >>> ParentB Init # >>> Grandparent Init
0 của các lớp phía sau lớpclass Grandparent: def __init__[self]: print["Grandparent Init"] class ParentA[Grandparent]: def __init__[self]: print["ParentA Init"] GrandParent.__init__[self] class ParentB[Grandparent]: def __init__[self]: print["ParentB Init"] GrandParent.__init__[self] class Children[ParentA, ParentB]: def __init__[self]: print["Children Init"] ParentA.__init__[self] ParentB.__init__[self] Children[] # >>> Children Init # >>> ParentA Init # >>> Grandparent Init # >>> ParentB Init # >>> Grandparent Init
1 trong MRO. Ở đây MRO sẽ làclass Grandparent: def __init__[self]: print["Grandparent Init"] class ParentA[Grandparent]: def __init__[self]: print["ParentA Init"] GrandParent.__init__[self] class ParentB[Grandparent]: def __init__[self]: print["ParentB Init"] GrandParent.__init__[self] class Children[ParentA, ParentB]: def __init__[self]: print["Children Init"] ParentA.__init__[self] ParentB.__init__[self] Children[] # >>> Children Init # >>> ParentA Init # >>> Grandparent Init # >>> ParentB Init # >>> Grandparent Init
5, vìclass Grandparent: def __init__[self]: print["Grandparent Init"] class ParentA[Grandparent]: def __init__[self]: print["ParentA Init"] GrandParent.__init__[self] class ParentB[Grandparent]: def __init__[self]: print["ParentB Init"] GrandParent.__init__[self] class Children[ParentA, ParentB]: def __init__[self]: print["Children Init"] ParentA.__init__[self] ParentB.__init__[self] Children[] # >>> Children Init # >>> ParentA Init # >>> Grandparent Init # >>> ParentB Init # >>> Grandparent Init
4 không được cài đặtclass Grandparent: def call_method[self]: print["This is Grandparent method"] class Parent[Grandparent]: def call_method[self]: print["This is Parent method"] class Children[Parent]: def call_method[self]: # call call_method of GrandParent # class instead of Parent class super[Parent, self].call_method[] c = Children[] c.call_method[] # >>> This is Grandparent method
0 nên sẽ trả về lỗiclass Grandparent: def __init__[self]: print["Grandparent Init"] class ParentA[Grandparent]: def __init__[self]: print["ParentA Init"] GrandParent.__init__[self] class ParentB[Grandparent]: def __init__[self]: print["ParentB Init"] GrandParent.__init__[self] class Children[ParentA, ParentB]: def __init__[self]: print["Children Init"] ParentA.__init__[self] ParentB.__init__[self] Children[] # >>> Children Init # >>> ParentA Init # >>> Grandparent Init # >>> ParentB Init # >>> Grandparent Init
8 Nếu trongclass Grandparent: def __init__[self]: print["Grandparent Init"] class ParentA[Grandparent]: def __init__[self]: print["ParentA Init"] GrandParent.__init__[self] class ParentB[Grandparent]: def __init__[self]: print["ParentB Init"] GrandParent.__init__[self] class Children[ParentA, ParentB]: def __init__[self]: print["Children Init"] ParentA.__init__[self] ParentB.__init__[self] Children[] # >>> Children Init # >>> ParentA Init # >>> Grandparent Init # >>> ParentB Init # >>> Grandparent Init
0 của lớpclass Grandparent: def __init__[self]: print["Grandparent Init"] class ParentA[Grandparent]: def __init__[self]: print["ParentA Init"] GrandParent.__init__[self] class ParentB[Grandparent]: def __init__[self]: print["ParentB Init"] GrandParent.__init__[self] class Children[ParentA, ParentB]: def __init__[self]: print["Children Init"] ParentA.__init__[self] ParentB.__init__[self] Children[] # >>> Children Init # >>> ParentA Init # >>> Grandparent Init # >>> ParentB Init # >>> Grandparent Init
1 gọi tiếpclass Grandparent: def __init__[self]: print["Grandparent Init"] class ParentA[Grandparent]: def __init__[self]: print["ParentA Init"] GrandParent.__init__[self] class ParentB[Grandparent]: def __init__[self]: print["ParentB Init"] GrandParent.__init__[self] class Children[ParentA, ParentB]: def __init__[self]: print["Children Init"] ParentA.__init__[self] ParentB.__init__[self] Children[] # >>> Children Init # >>> ParentA Init # >>> Grandparent Init # >>> ParentB Init # >>> Grandparent Init
2. Hàm sẽ tìmclass Grandparent: def __init__[self]: print["Grandparent Init"] class ParentA[Grandparent]: def __init__[self]: print["ParentA Init"] GrandParent.__init__[self] class ParentB[Grandparent]: def __init__[self]: print["ParentB Init"] GrandParent.__init__[self] class Children[ParentA, ParentB]: def __init__[self]: print["Children Init"] ParentA.__init__[self] ParentB.__init__[self] Children[] # >>> Children Init # >>> ParentA Init # >>> Grandparent Init # >>> ParentB Init # >>> Grandparent Init
0 của các lớp phía sau lớpclass Grandparent: def __init__[self]: print["Grandparent Init"] class ParentA[Grandparent]: def __init__[self]: print["ParentA Init"] GrandParent.__init__[self] class ParentB[Grandparent]: def __init__[self]: print["ParentB Init"] GrandParent.__init__[self] class Children[ParentA, ParentB]: def __init__[self]: print["Children Init"] ParentA.__init__[self] ParentB.__init__[self] Children[] # >>> Children Init # >>> ParentA Init # >>> Grandparent Init # >>> ParentB Init # >>> Grandparent Init
1 trong MRO. Ở đây MRO sẽ làclass Grandparent: def __init__[self]: print["Grandparent Init"] class ParentA[Grandparent]: def __init__[self]: print["ParentA Init"] GrandParent.__init__[self] class ParentB[Grandparent]: def __init__[self]: print["ParentB Init"] GrandParent.__init__[self] class Children[ParentA, ParentB]: def __init__[self]: print["Children Init"] ParentA.__init__[self] ParentB.__init__[self] Children[] # >>> Children Init # >>> ParentA Init # >>> Grandparent Init # >>> ParentB Init # >>> Grandparent Init
5, vìclass Grandparent: def __init__[self]: print["Grandparent Init"] class ParentA[Grandparent]: def __init__[self]: print["ParentA Init"] GrandParent.__init__[self] class ParentB[Grandparent]: def __init__[self]: print["ParentB Init"] GrandParent.__init__[self] class Children[ParentA, ParentB]: def __init__[self]: print["Children Init"] ParentA.__init__[self] ParentB.__init__[self] Children[] # >>> Children Init # >>> ParentA Init # >>> Grandparent Init # >>> ParentB Init # >>> Grandparent Init
4 không được cài đặtclass Grandparent: def call_method[self]: print["This is Grandparent method"] class Parent[Grandparent]: def call_method[self]: print["This is Parent method"] class Children[Parent]: def call_method[self]: # call call_method of GrandParent # class instead of Parent class super[Parent, self].call_method[] c = Children[] c.call_method[] # >>> This is Grandparent method
0 nên sẽ trả về lỗiclass Grandparent: def __init__[self]: print["Grandparent Init"] class ParentA[Grandparent]: def __init__[self]: print["ParentA Init"] GrandParent.__init__[self] class ParentB[Grandparent]: def __init__[self]: print["ParentB Init"] GrandParent.__init__[self] class Children[ParentA, ParentB]: def __init__[self]: print["Children Init"] ParentA.__init__[self] ParentB.__init__[self] Children[] # >>> Children Init # >>> ParentA Init # >>> Grandparent Init # >>> ParentB Init # >>> Grandparent Init
8class Grandparent: def __init__[self]: print["Grandparent Init"] class ParentA[Grandparent]: def __init__[self]: print["ParentA Init"] GrandParent.__init__[self] class ParentB[Grandparent]: def __init__[self]: print["ParentB Init"] GrandParent.__init__[self] class Children[ParentA, ParentB]: def __init__[self]: print["Children Init"] ParentA.__init__[self] ParentB.__init__[self] Children[] # >>> Children Init # >>> ParentA Init # >>> Grandparent Init # >>> ParentB Init # >>> Grandparent Init
4. Giải quyết Diamond Problem bằng super[]
Diamond Problem xuất hiện khi ta thực hiện đa kế thừa trên hai lớp cha cùng kế thừa từ một lớp ông nội. Xét trường hợp ta có các lớp sau:
Xét trường hợp ta có các lớp sau:
- Lớp
1class Grandparent: def __init__[self]: print["Grandparent Init"] class ParentA[Grandparent]: def __init__[self]: print["ParentA Init"] GrandParent.__init__[self] class ParentB[Grandparent]: def __init__[self]: print["ParentB Init"] GrandParent.__init__[self] class Children[ParentA, ParentB]: def __init__[self]: print["Children Init"] ParentA.__init__[self] ParentB.__init__[self] Children[] # >>> Children Init # >>> ParentA Init # >>> Grandparent Init # >>> ParentB Init # >>> Grandparent Init
- Lớp
0 vàclass Grandparent: def __init__[self]: print["Grandparent Init"] class ParentA[Grandparent]: def __init__[self]: print["ParentA Init"] super[].__init__[] class ParentB[Grandparent]: def __init__[self]: print["ParentB Init"] super[].__init__[] class Children[ParentA, ParentB]: def __init__[self]: print["Children Init"] super[].__init__[] Children[] # >>> Children Init # >>> ParentA Init # >>> ParentB Init # >>> Grandparent Init
1 cùng kế thừa từ lớpclass Grandparent: def __init__[self]: print["Grandparent Init"] class ParentA[Grandparent]: def __init__[self]: print["ParentA Init"] super[].__init__[] class ParentB[Grandparent]: def __init__[self]: print["ParentB Init"] super[].__init__[] class Children[ParentA, ParentB]: def __init__[self]: print["Children Init"] super[].__init__[] Children[] # >>> Children Init # >>> ParentA Init # >>> ParentB Init # >>> Grandparent Init
2class Grandparent: def __init__[self]: print["Grandparent Init"] class ParentA[Grandparent]: def __init__[self]: print["ParentA Init"] super[].__init__[] class ParentB[Grandparent]: def __init__[self]: print["ParentB Init"] super[].__init__[] class Children[ParentA, ParentB]: def __init__[self]: print["Children Init"] super[].__init__[] Children[] # >>> Children Init # >>> ParentA Init # >>> ParentB Init # >>> Grandparent Init
- Lớp
3 đa kế thừa từ hai lớpclass Grandparent: def __init__[self]: print["Grandparent Init"] class ParentA[Grandparent]: def __init__[self]: print["ParentA Init"] super[].__init__[] class ParentB[Grandparent]: def __init__[self]: print["ParentB Init"] super[].__init__[] class Children[ParentA, ParentB]: def __init__[self]: print["Children Init"] super[].__init__[] Children[] # >>> Children Init # >>> ParentA Init # >>> ParentB Init # >>> Grandparent Init
4 vàclass Grandparent: def __init__[self]: print["Grandparent Init"] class ParentA[Grandparent]: def __init__[self]: print["ParentA Init"] super[].__init__[] class ParentB[Grandparent]: def __init__[self]: print["ParentB Init"] super[].__init__[] class Children[ParentA, ParentB]: def __init__[self]: print["Children Init"] super[].__init__[] Children[] # >>> Children Init # >>> ParentA Init # >>> ParentB Init # >>> Grandparent Init
5class Grandparent: def __init__[self]: print["Grandparent Init"] class ParentA[Grandparent]: def __init__[self]: print["ParentA Init"] super[].__init__[] class ParentB[Grandparent]: def __init__[self]: print["ParentB Init"] super[].__init__[] class Children[ParentA, ParentB]: def __init__[self]: print["Children Init"] super[].__init__[] Children[] # >>> Children Init # >>> ParentA Init # >>> ParentB Init # >>> Grandparent Init
Khi đó chúng ta sẽ gặp các vấn đề phát sinh sau:
4 và class Grandparent:
def __init__[self]:
print["Grandparent Init"]
class ParentA[Grandparent]:
def __init__[self]:
print["ParentA Init"]
super[].__init__[]
class ParentB[Grandparent]:
def __init__[self]:
print["ParentB Init"]
super[].__init__[]
class Children[ParentA, ParentB]:
def __init__[self]:
print["Children Init"]
super[].__init__[]
Children[]
# >>> Children Init
# >>> ParentA Init
# >>> ParentB Init
# >>> Grandparent Init
5 có phương thức trùng tên nhauclass Grandparent:
def __init__[self]:
print["Grandparent Init"]
class ParentA[Grandparent]:
def __init__[self]:
print["ParentA Init"]
super[].__init__[]
class ParentB[Grandparent]:
def __init__[self]:
print["ParentB Init"]
super[].__init__[]
class Children[ParentA, ParentB]:
def __init__[self]:
print["Children Init"]
super[].__init__[]
Children[]
# >>> Children Init
# >>> ParentA Init
# >>> ParentB Init
# >>> Grandparent Init
Nếu bạn gọi phương thức bằng
class Parent:
def self_intro[self]:
print["This is parent class"]
def parent_method[self]:
print["This is parent method"]
class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
Parent.self_intro[self]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
2, phương thức của lớp có thứ tự nhỏ hơn trong MRO sẽ được gọi trước. Trong trường hợp này, thứ tự lớp cha trong MRO sẽ là thứ tự liệt kê lớp cha trong lúc khai báo lớp class Parent:
def self_intro[self]:
print["This is parent class"]
def parent_method[self]:
print["This is parent method"]
class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
Parent.self_intro[self]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
7.class Grandparent:
def call_method[self]:
print["This is Grandparent method"]
class ParentA[Grandparent]:
def call_method[self]:
print["This is ParentA method"]
class ParentB[Grandparent]:
def call_method[self]:
print["This is ParentB method"]
class Children[ParentA, ParentB]:
def say_name[self]:
super[].say_name[]
c = Children[]
print[Children.mro[]]
# >>> [, ,
# , , ]
c.call_method[]
# >>> This is ParentA method
Nếu muốn gọi
class Grandparent:
def __init__[self]:
print["Grandparent Init"]
class ParentA[Grandparent]:
def __init__[self]:
print["ParentA Init"]
GrandParent.__init__[self]
class ParentB[Grandparent]:
def __init__[self]:
print["ParentB Init"]
GrandParent.__init__[self]
class Children[ParentA, ParentB]:
def __init__[self]:
print["Children Init"]
ParentA.__init__[self]
ParentB.__init__[self]
Children[]
# >>> Children Init
# >>> ParentA Init
# >>> Grandparent Init
# >>> ParentB Init
# >>> Grandparent Init
0 của class Grandparent:
def __init__[self]:
print["Grandparent Init"]
class ParentA[Grandparent]:
def __init__[self]:
print["ParentA Init"]
super[].__init__[]
class ParentB[Grandparent]:
def __init__[self]:
print["ParentB Init"]
super[].__init__[]
class Children[ParentA, ParentB]:
def __init__[self]:
print["Children Init"]
super[].__init__[]
Children[]
# >>> Children Init
# >>> ParentA Init
# >>> ParentB Init
# >>> Grandparent Init
5 ta có thể làm như sau:- Đổi thứ tự khai báo
2class Grandparent: def __init__[self, gp_age]: self.gp_age = gp_age print[f"Grandparent age: {self.gp_age}"] class ParentB[Grandparent]: def __init__[self, pb_age, gp_age]: self.pb_age = pb_age print[f"ParentB age: {self.pb_age}"] super[].__init__[gp_age] class ParentA[Grandparent]: def __init__[self, pa_age, pb_age, gp_age]: self.pa_age = pa_age print[f"ParentA age: {self.pa_age}"] super[].__init__[pb_age, gp_age] class Children[ParentA, ParentB]: def __init__[self, c_age, pa_age, pb_age, gp_age]: self.c_age = c_age print[f"Children age: {self.c_age}"] super[].__init__[pa_age, pb_age, gp_age] Children[c_age="15", pa_age="40", pb_age="45", gp_age="70"] # >>> Children age: 15 # >>> ParentA age: 40 # >>> ParentB age: 45 # >>> Grandparent age: 70
- Gọi trực tiếp
3class Grandparent: def __init__[self, gp_age]: self.gp_age = gp_age print[f"Grandparent age: {self.gp_age}"] class ParentB[Grandparent]: def __init__[self, pb_age, gp_age]: self.pb_age = pb_age print[f"ParentB age: {self.pb_age}"] super[].__init__[gp_age] class ParentA[Grandparent]: def __init__[self, pa_age, pb_age, gp_age]: self.pa_age = pa_age print[f"ParentA age: {self.pa_age}"] super[].__init__[pb_age, gp_age] class Children[ParentA, ParentB]: def __init__[self, c_age, pa_age, pb_age, gp_age]: self.c_age = c_age print[f"Children age: {self.c_age}"] super[].__init__[pa_age, pb_age, gp_age] Children[c_age="15", pa_age="40", pb_age="45", gp_age="70"] # >>> Children age: 15 # >>> ParentA age: 40 # >>> ParentB age: 45 # >>> Grandparent age: 70
Phương thức của lớp
1 được gọi lại hai lầnclass Grandparent:
def __init__[self]:
print["Grandparent Init"]
class ParentA[Grandparent]:
def __init__[self]:
print["ParentA Init"]
GrandParent.__init__[self]
class ParentB[Grandparent]:
def __init__[self]:
print["ParentB Init"]
GrandParent.__init__[self]
class Children[ParentA, ParentB]:
def __init__[self]:
print["Children Init"]
ParentA.__init__[self]
ParentB.__init__[self]
Children[]
# >>> Children Init
# >>> ParentA Init
# >>> Grandparent Init
# >>> ParentB Init
# >>> Grandparent Init
Vấn đề này gặp khi chúng ta muốn gọi phương thức khởi tạo của
class Grandparent:
def __init__[self]:
print["Grandparent Init"]
class ParentA[Grandparent]:
def __init__[self]:
print["ParentA Init"]
super[].__init__[]
class ParentB[Grandparent]:
def __init__[self]:
print["ParentB Init"]
super[].__init__[]
class Children[ParentA, ParentB]:
def __init__[self]:
print["Children Init"]
super[].__init__[]
Children[]
# >>> Children Init
# >>> ParentA Init
# >>> ParentB Init
# >>> Grandparent Init
4 và class Grandparent:
def __init__[self]:
print["Grandparent Init"]
class ParentA[Grandparent]:
def __init__[self]:
print["ParentA Init"]
super[].__init__[]
class ParentB[Grandparent]:
def __init__[self]:
print["ParentB Init"]
super[].__init__[]
class Children[ParentA, ParentB]:
def __init__[self]:
print["Children Init"]
super[].__init__[]
Children[]
# >>> Children Init
# >>> ParentA Init
# >>> ParentB Init
# >>> Grandparent Init
5 trực tiếp bên trong class Parent:
def self_intro[self]:
print["This is parent class"]
def parent_method[self]:
print["This is parent method"]
class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
Parent.self_intro[self]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
7, nhưng phương thức khởi tạo của class Grandparent:
def __init__[self]:
print["Grandparent Init"]
class ParentA[Grandparent]:
def __init__[self]:
print["ParentA Init"]
super[].__init__[]
class ParentB[Grandparent]:
def __init__[self]:
print["ParentB Init"]
super[].__init__[]
class Children[ParentA, ParentB]:
def __init__[self]:
print["Children Init"]
super[].__init__[]
Children[]
# >>> Children Init
# >>> ParentA Init
# >>> ParentB Init
# >>> Grandparent Init
4 và class Grandparent:
def __init__[self]:
print["Grandparent Init"]
class ParentA[Grandparent]:
def __init__[self]:
print["ParentA Init"]
super[].__init__[]
class ParentB[Grandparent]:
def __init__[self]:
print["ParentB Init"]
super[].__init__[]
class Children[ParentA, ParentB]:
def __init__[self]:
print["Children Init"]
super[].__init__[]
Children[]
# >>> Children Init
# >>> ParentA Init
# >>> ParentB Init
# >>> Grandparent Init
5 lại gọi phương thức khởi tạo của class Grandparent:
def __init__[self]:
print["Grandparent Init"]
class ParentA[Grandparent]:
def __init__[self]:
print["ParentA Init"]
super[].__init__[]
class ParentB[Grandparent]:
def __init__[self]:
print["ParentB Init"]
super[].__init__[]
class Children[ParentA, ParentB]:
def __init__[self]:
print["Children Init"]
super[].__init__[]
Children[]
# >>> Children Init
# >>> ParentA Init
# >>> ParentB Init
# >>> Grandparent Init
2. Khi đó sẽ xảy ra việc phương thức khởi tạo của class Grandparent:
def __init__[self]:
print["Grandparent Init"]
class ParentA[Grandparent]:
def __init__[self]:
print["ParentA Init"]
super[].__init__[]
class ParentB[Grandparent]:
def __init__[self]:
print["ParentB Init"]
super[].__init__[]
class Children[ParentA, ParentB]:
def __init__[self]:
print["Children Init"]
super[].__init__[]
Children[]
# >>> Children Init
# >>> ParentA Init
# >>> ParentB Init
# >>> Grandparent Init
2 bị gọi 2 lần.class Grandparent:
def __init__[self]:
print["Grandparent Init"]
class ParentA[Grandparent]:
def __init__[self]:
print["ParentA Init"]
GrandParent.__init__[self]
class ParentB[Grandparent]:
def __init__[self]:
print["ParentB Init"]
GrandParent.__init__[self]
class Children[ParentA, ParentB]:
def __init__[self]:
print["Children Init"]
ParentA.__init__[self]
ParentB.__init__[self]
Children[]
# >>> Children Init
# >>> ParentA Init
# >>> Grandparent Init
# >>> ParentB Init
# >>> Grandparent Init
Cách giải quyết: sử dụng hàm
2 thay vì gọi trực tiếp. Như đã lưu ý ở mục 3. hàm class Parent:
def self_intro[self]:
print["This is parent class"]
def parent_method[self]:
print["This is parent method"]
class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
Parent.self_intro[self]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
2 sẽ tìm các phương thức khởi tạo dựa trên MRO và lớp hiện tại. Vì các lớp chỉ xuất hiện trong MRO duy nhất một lần nên khi gọi class Parent:
def self_intro[self]:
print["This is parent class"]
def parent_method[self]:
print["This is parent method"]
class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
Parent.self_intro[self]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
0 sẽ tránh được việc gọi nhiều lần, giảm thiểu thời gian chạy và tránh bị ghi đè không cần thiết. sử dụng hàm class Parent:
def self_intro[self]:
print["This is parent class"]
def parent_method[self]:
print["This is parent method"]
class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
Parent.self_intro[self]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
class Parent:
def self_intro[self]:
print["This is parent class"]
def parent_method[self]:
print["This is parent method"]
class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
Parent.self_intro[self]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
2 thay vì gọi trực tiếp. Như đã lưu ý ở mục 3. hàm class Parent:
def self_intro[self]:
print["This is parent class"]
def parent_method[self]:
print["This is parent method"]
class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
Parent.self_intro[self]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
2 sẽ tìm các phương thức khởi tạo dựa trên MRO và lớp hiện tại. Vì các
lớp chỉ xuất hiện trong MRO duy nhất một lần nên khi gọi class Parent:
def self_intro[self]:
print["This is parent class"]
def parent_method[self]:
print["This is parent method"]
class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
Parent.self_intro[self]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
0 sẽ tránh được việc gọi nhiều lần, giảm thiểu thời gian chạy và tránh bị ghi đè không cần thiết.class Grandparent:
def __init__[self]:
print["Grandparent Init"]
class ParentA[Grandparent]:
def __init__[self]:
print["ParentA Init"]
super[].__init__[]
class ParentB[Grandparent]:
def __init__[self]:
print["ParentB Init"]
super[].__init__[]
class Children[ParentA, ParentB]:
def __init__[self]:
print["Children Init"]
super[].__init__[]
Children[]
# >>> Children Init
# >>> ParentA Init
# >>> ParentB Init
# >>> Grandparent Init
Tuy nhiên cách này lại dẫn đến vấn đề sau
Phương thức khởi tạo của
4 và class Grandparent:
def __init__[self]:
print["Grandparent Init"]
class ParentA[Grandparent]:
def __init__[self]:
print["ParentA Init"]
super[].__init__[]
class ParentB[Grandparent]:
def __init__[self]:
print["ParentB Init"]
super[].__init__[]
class Children[ParentA, ParentB]:
def __init__[self]:
print["Children Init"]
super[].__init__[]
Children[]
# >>> Children Init
# >>> ParentA Init
# >>> ParentB Init
# >>> Grandparent Init
5 cần các tham số khác nhau Giả sử ta cần lưu số tuổi của mỗi lớp thông qua các biến class Grandparent:
def __init__[self]:
print["Grandparent Init"]
class ParentA[Grandparent]:
def __init__[self]:
print["ParentA Init"]
super[].__init__[]
class ParentB[Grandparent]:
def __init__[self]:
print["ParentB Init"]
super[].__init__[]
class Children[ParentA, ParentB]:
def __init__[self]:
print["Children Init"]
super[].__init__[]
Children[]
# >>> Children Init
# >>> ParentA Init
# >>> ParentB Init
# >>> Grandparent Init
7, class Grandparent:
def __init__[self, gp_age, **kwargs]:
self.gp_age = gp_age
print[f"Grandparent age: {self.gp_age}"]
class ParentB[Grandparent]:
def __init__[self, pb_age, **kwargs]:
self.pb_age = pb_age
print[f"ParrentB age: {self.pb_age}"]
super[].__init__[**kwargs]
class ParentA[Grandparent]:
def __init__[self, pa_age, **kwargs]:
self.pa_age = pa_age
print[f"ParentA age: {self.pa_age}"]
super[].__init__[**kwargs]
class Children[ParentA, ParentB]:
def __init__[self, c_age, **kwargs]:
self.c_age = c_age
print[f"Children age: {self.c_age}"]
super[].__init__[**kwargs]
Children[c_age="15", pa_age="40", pb_age="45", gp_age="70"]
# >>> Children age: 15
# >>> ParentA age: 40
# >>> ParentB age: 45
# >>> Grandparent age: 70
8, class Grandparent:
def __init__[self, gp_age, **kwargs]:
self.gp_age = gp_age
print[f"Grandparent age: {self.gp_age}"]
class ParentB[Grandparent]:
def __init__[self, pb_age, **kwargs]:
self.pb_age = pb_age
print[f"ParrentB age: {self.pb_age}"]
super[].__init__[**kwargs]
class ParentA[Grandparent]:
def __init__[self, pa_age, **kwargs]:
self.pa_age = pa_age
print[f"ParentA age: {self.pa_age}"]
super[].__init__[**kwargs]
class Children[ParentA, ParentB]:
def __init__[self, c_age, **kwargs]:
self.c_age = c_age
print[f"Children age: {self.c_age}"]
super[].__init__[**kwargs]
Children[c_age="15", pa_age="40", pb_age="45", gp_age="70"]
# >>> Children age: 15
# >>> ParentA age: 40
# >>> ParentB age: 45
# >>> Grandparent age: 70
9 và class Grandparent:
def __init__[self, gp_age, **kwargs]:
self.gp_age = gp_age
print[f"Grandparent age: {self.gp_age}"]
class ParentB[Grandparent]:
def __init__[self, pb_age, **kwargs]:
self.pb_age = pb_age
print[f"ParrentB age: {self.pb_age}"]
super[].__init__[**kwargs]
class ParentA[Grandparent]:
def __init__[self, pa_age, **kwargs]:
self.pa_age = pa_age
print[f"ParentA age: {self.pa_age}"]
super[].__init__[**kwargs]
class Children[ParentA, ParentB]:
def __init__[self, c_age, **kwargs]:
self.c_age = c_age
print[f"Children age: {self.c_age}"]
super[].__init__[**kwargs]
Children[c_age="15", pa_age="40", pb_age="45", gp_age="70"]
# >>> Children age: 15
# >>> ParentA age: 40
# >>> ParentB age: 45
# >>> Grandparent age: 70
00 Xét đoạn code sau đây:class Parent:
def self_intro[self]:
print["This is parent class"]
def parent_method[self]:
print["This is parent method"]
class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
Parent.self_intro[self]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
Giả sử ta cần lưu số tuổi của mỗi lớp thông qua các biến
class Grandparent:
def __init__[self, gp_age, **kwargs]:
self.gp_age = gp_age
print[f"Grandparent age: {self.gp_age}"]
class ParentB[Grandparent]:
def __init__[self, pb_age, **kwargs]:
self.pb_age = pb_age
print[f"ParrentB age: {self.pb_age}"]
super[].__init__[**kwargs]
class ParentA[Grandparent]:
def __init__[self, pa_age, **kwargs]:
self.pa_age = pa_age
print[f"ParentA age: {self.pa_age}"]
super[].__init__[**kwargs]
class Children[ParentA, ParentB]:
def __init__[self, c_age, **kwargs]:
self.c_age = c_age
print[f"Children age: {self.c_age}"]
super[].__init__[**kwargs]
Children[c_age="15", pa_age="40", pb_age="45", gp_age="70"]
# >>> Children age: 15
# >>> ParentA age: 40
# >>> ParentB age: 45
# >>> Grandparent age: 70
7, class Grandparent:
def __init__[self, gp_age, **kwargs]:
self.gp_age = gp_age
print[f"Grandparent age: {self.gp_age}"]
class ParentB[Grandparent]:
def __init__[self, pb_age, **kwargs]:
self.pb_age = pb_age
print[f"ParrentB age: {self.pb_age}"]
super[].__init__[**kwargs]
class ParentA[Grandparent]:
def __init__[self, pa_age, **kwargs]:
self.pa_age = pa_age
print[f"ParentA age: {self.pa_age}"]
super[].__init__[**kwargs]
class Children[ParentA, ParentB]:
def __init__[self, c_age, **kwargs]:
self.c_age = c_age
print[f"Children age: {self.c_age}"]
super[].__init__[**kwargs]
Children[c_age="15", pa_age="40", pb_age="45", gp_age="70"]
# >>> Children age: 15
# >>> ParentA age: 40
# >>> ParentB age: 45
# >>> Grandparent age: 70
8, class Grandparent:
def __init__[self, gp_age, **kwargs]:
self.gp_age = gp_age
print[f"Grandparent age: {self.gp_age}"]
class ParentB[Grandparent]:
def __init__[self, pb_age, **kwargs]:
self.pb_age = pb_age
print[f"ParrentB age: {self.pb_age}"]
super[].__init__[**kwargs]
class ParentA[Grandparent]:
def __init__[self, pa_age, **kwargs]:
self.pa_age = pa_age
print[f"ParentA age: {self.pa_age}"]
super[].__init__[**kwargs]
class Children[ParentA, ParentB]:
def __init__[self, c_age, **kwargs]:
self.c_age = c_age
print[f"Children age: {self.c_age}"]
super[].__init__[**kwargs]
Children[c_age="15", pa_age="40", pb_age="45", gp_age="70"]
# >>> Children age: 15
# >>> ParentA age: 40
# >>> ParentB age: 45
# >>> Grandparent age: 70
9 và class Parent:
def self_intro[self]:
print["This is parent class"]
def parent_method[self]:
print["This is parent method"]
class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
Parent.self_intro[self]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
00Xét đoạn code sau đây:
class Grandparent:
def __init__[self, gp_age]:
self.gp_age = gp_age
print[f"Grandparent age: {self.gp_age}"]
class ParentB[Grandparent]:
def __init__[self, pb_age, gp_age]:
self.pb_age = pb_age
print[f"ParentB age: {self.pb_age}"]
super[].__init__[gp_age]
class ParentA[Grandparent]:
def __init__[self, pa_age, pb_age, gp_age]:
self.pa_age = pa_age
print[f"ParentA age: {self.pa_age}"]
super[].__init__[pb_age, gp_age]
class Children[ParentA, ParentB]:
def __init__[self, c_age, pa_age, pb_age, gp_age]:
self.c_age = c_age
print[f"Children age: {self.c_age}"]
super[].__init__[pa_age, pb_age, gp_age]
Children[c_age="15", pa_age="40", pb_age="45", gp_age="70"]
# >>> Children age: 15
# >>> ParentA age: 40
# >>> ParentB age: 45
# >>> Grandparent age: 70
Mỗi lớp đều cần một tham số khác nhau khi khởi tạo nên theo thứ tự MRO biết trước, chúng ta có thể viết code như trên. Tuy code chạy đúng như ý muốn nhưng mình tin chẳng ai muốn code như trên vì các lí do sau:
- Sai bản chất: trừ khi
4 vàclass Grandparent: def __init__[self]: print["Grandparent Init"] class ParentA[Grandparent]: def __init__[self]: print["ParentA Init"] super[].__init__[] class ParentB[Grandparent]: def __init__[self]: print["ParentB Init"] super[].__init__[] class Children[ParentA, ParentB]: def __init__[self]: print["Children Init"] super[].__init__[] Children[] # >>> Children Init # >>> ParentA Init # >>> ParentB Init # >>> Grandparent Init
5 chỉ được khởi tạo đúng một lần và chỉ dùng để tạo lớpclass Grandparent: def __init__[self]: print["Grandparent Init"] class ParentA[Grandparent]: def __init__[self]: print["ParentA Init"] super[].__init__[] class ParentB[Grandparent]: def __init__[self]: print["ParentB Init"] super[].__init__[] class Children[ParentA, ParentB]: def __init__[self]: print["Children Init"] super[].__init__[] Children[] # >>> Children Init # >>> ParentA Init # >>> ParentB Init # >>> Grandparent Init
7, với code trên khi tạo đối tượng thuộc lớpclass Parent: def self_intro[self]: print["This is parent class"] def parent_method[self]: print["This is parent method"] class Children[Parent]: def self_intro[self]: print["This is children class"] def family_intro[self]: self.self_intro[] # Same as Children.self_intro[self] Parent.self_intro[self] c = Children[] c.family_intro[] # >>> This is children class # >>> This is parent class
4 hoặcclass Grandparent: def __init__[self]: print["Grandparent Init"] class ParentA[Grandparent]: def __init__[self]: print["ParentA Init"] super[].__init__[] class ParentB[Grandparent]: def __init__[self]: print["ParentB Init"] super[].__init__[] class Children[ParentA, ParentB]: def __init__[self]: print["Children Init"] super[].__init__[] Children[] # >>> Children Init # >>> ParentA Init # >>> ParentB Init # >>> Grandparent Init
5 sẽ bị lỗi dư tham số. trừ khiclass Grandparent: def __init__[self]: print["Grandparent Init"] class ParentA[Grandparent]: def __init__[self]: print["ParentA Init"] super[].__init__[] class ParentB[Grandparent]: def __init__[self]: print["ParentB Init"] super[].__init__[] class Children[ParentA, ParentB]: def __init__[self]: print["Children Init"] super[].__init__[] Children[] # >>> Children Init # >>> ParentA Init # >>> ParentB Init # >>> Grandparent Init
4 vàclass Grandparent: def __init__[self]: print["Grandparent Init"] class ParentA[Grandparent]: def __init__[self]: print["ParentA Init"] super[].__init__[] class ParentB[Grandparent]: def __init__[self]: print["ParentB Init"] super[].__init__[] class Children[ParentA, ParentB]: def __init__[self]: print["Children Init"] super[].__init__[] Children[] # >>> Children Init # >>> ParentA Init # >>> ParentB Init # >>> Grandparent Init
5 chỉ được khởi tạo đúng một lần và chỉ dùng để tạo lớpclass Grandparent: def __init__[self]: print["Grandparent Init"] class ParentA[Grandparent]: def __init__[self]: print["ParentA Init"] super[].__init__[] class ParentB[Grandparent]: def __init__[self]: print["ParentB Init"] super[].__init__[] class Children[ParentA, ParentB]: def __init__[self]: print["Children Init"] super[].__init__[] Children[] # >>> Children Init # >>> ParentA Init # >>> ParentB Init # >>> Grandparent Init
7, với code trên khi tạo đối tượng thuộc lớpclass Parent: def self_intro[self]: print["This is parent class"] def parent_method[self]: print["This is parent method"] class Children[Parent]: def self_intro[self]: print["This is children class"] def family_intro[self]: self.self_intro[] # Same as Children.self_intro[self] Parent.self_intro[self] c = Children[] c.family_intro[] # >>> This is children class # >>> This is parent class
4 hoặcclass Grandparent: def __init__[self]: print["Grandparent Init"] class ParentA[Grandparent]: def __init__[self]: print["ParentA Init"] super[].__init__[] class ParentB[Grandparent]: def __init__[self]: print["ParentB Init"] super[].__init__[] class Children[ParentA, ParentB]: def __init__[self]: print["Children Init"] super[].__init__[] Children[] # >>> Children Init # >>> ParentA Init # >>> ParentB Init # >>> Grandparent Init
5 sẽ bị lỗi dư tham số.class Grandparent: def __init__[self]: print["Grandparent Init"] class ParentA[Grandparent]: def __init__[self]: print["ParentA Init"] super[].__init__[] class ParentB[Grandparent]: def __init__[self]: print["ParentB Init"] super[].__init__[] class Children[ParentA, ParentB]: def __init__[self]: print["Children Init"] super[].__init__[] Children[] # >>> Children Init # >>> ParentA Init # >>> ParentB Init # >>> Grandparent Init
- Quá cứng nhắc: Vì tham số truyền vào
06 dựa trên MRO nên sẽ phụ thuộc thứ tự khai báo của lớp, nên chỉ cần thay đổi lại thứ tự có thể làm code chạy bị lỗi. Vì tham số truyền vàoclass Parent: def self_intro[self]: print["This is parent class"] def parent_method[self]: print["This is parent method"] class Children[Parent]: def self_intro[self]: print["This is children class"] def family_intro[self]: self.self_intro[] # Same as Children.self_intro[self] Parent.self_intro[self] c = Children[] c.family_intro[] # >>> This is children class # >>> This is parent class
06 dựa trên MRO nên sẽ phụ thuộc thứ tự khai báo của lớp, nên chỉ cần thay đổi lại thứ tự có thể làm code chạy bị lỗi.class Parent: def self_intro[self]: print["This is parent class"] def parent_method[self]: print["This is parent method"] class Children[Parent]: def self_intro[self]: print["This is children class"] def family_intro[self]: self.self_intro[] # Same as Children.self_intro[self] Parent.self_intro[self] c = Children[] c.family_intro[] # >>> This is children class # >>> This is parent class
- Khó tái sử dụng: Giả sử như chúng ta có thêm lớp
07 và muốn tạo lớp đa kế thừa từclass Parent: def self_intro[self]: print["This is parent class"] def parent_method[self]: print["This is parent method"] class Children[Parent]: def self_intro[self]: print["This is children class"] def family_intro[self]: self.self_intro[] # Same as Children.self_intro[self] Parent.self_intro[self] c = Children[] c.family_intro[] # >>> This is children class # >>> This is parent class
4 vàclass Grandparent: def __init__[self]: print["Grandparent Init"] class ParentA[Grandparent]: def __init__[self]: print["ParentA Init"] super[].__init__[] class ParentB[Grandparent]: def __init__[self]: print["ParentB Init"] super[].__init__[] class Children[ParentA, ParentB]: def __init__[self]: print["Children Init"] super[].__init__[] Children[] # >>> Children Init # >>> ParentA Init # >>> ParentB Init # >>> Grandparent Init
07. Khi đó ta phải viết lạiclass Parent: def self_intro[self]: print["This is parent class"] def parent_method[self]: print["This is parent method"] class Children[Parent]: def self_intro[self]: print["This is children class"] def family_intro[self]: self.self_intro[] # Same as Children.self_intro[self] Parent.self_intro[self] c = Children[] c.family_intro[] # >>> This is children class # >>> This is parent class
06 củaclass Parent: def self_intro[self]: print["This is parent class"] def parent_method[self]: print["This is parent method"] class Children[Parent]: def self_intro[self]: print["This is children class"] def family_intro[self]: self.self_intro[] # Same as Children.self_intro[self] Parent.self_intro[self] c = Children[] c.family_intro[] # >>> This is children class # >>> This is parent class
4 để đa kế thừa, điều này có thể làm ảnh hưởng đến lớpclass Grandparent: def __init__[self]: print["Grandparent Init"] class ParentA[Grandparent]: def __init__[self]: print["ParentA Init"] super[].__init__[] class ParentB[Grandparent]: def __init__[self]: print["ParentB Init"] super[].__init__[] class Children[ParentA, ParentB]: def __init__[self]: print["Children Init"] super[].__init__[] Children[] # >>> Children Init # >>> ParentA Init # >>> ParentB Init # >>> Grandparent Init
7 hiện tại. Giả sử như chúng ta có thêm lớpclass Parent: def self_intro[self]: print["This is parent class"] def parent_method[self]: print["This is parent method"] class Children[Parent]: def self_intro[self]: print["This is children class"] def family_intro[self]: self.self_intro[] # Same as Children.self_intro[self] Parent.self_intro[self] c = Children[] c.family_intro[] # >>> This is children class # >>> This is parent class
07 và muốn tạo lớp đa kế thừa từclass Parent: def self_intro[self]: print["This is parent class"] def parent_method[self]: print["This is parent method"] class Children[Parent]: def self_intro[self]: print["This is children class"] def family_intro[self]: self.self_intro[] # Same as Children.self_intro[self] Parent.self_intro[self] c = Children[] c.family_intro[] # >>> This is children class # >>> This is parent class
4 vàclass Grandparent: def __init__[self]: print["Grandparent Init"] class ParentA[Grandparent]: def __init__[self]: print["ParentA Init"] super[].__init__[] class ParentB[Grandparent]: def __init__[self]: print["ParentB Init"] super[].__init__[] class Children[ParentA, ParentB]: def __init__[self]: print["Children Init"] super[].__init__[] Children[] # >>> Children Init # >>> ParentA Init # >>> ParentB Init # >>> Grandparent Init
07. Khi đó ta phải viết lạiclass Parent: def self_intro[self]: print["This is parent class"] def parent_method[self]: print["This is parent method"] class Children[Parent]: def self_intro[self]: print["This is children class"] def family_intro[self]: self.self_intro[] # Same as Children.self_intro[self] Parent.self_intro[self] c = Children[] c.family_intro[] # >>> This is children class # >>> This is parent class
06 củaclass Parent: def self_intro[self]: print["This is parent class"] def parent_method[self]: print["This is parent method"] class Children[Parent]: def self_intro[self]: print["This is children class"] def family_intro[self]: self.self_intro[] # Same as Children.self_intro[self] Parent.self_intro[self] c = Children[] c.family_intro[] # >>> This is children class # >>> This is parent class
4 để đa kế thừa, điều này có thể làm ảnh hưởng đến lớpclass Grandparent: def __init__[self]: print["Grandparent Init"] class ParentA[Grandparent]: def __init__[self]: print["ParentA Init"] super[].__init__[] class ParentB[Grandparent]: def __init__[self]: print["ParentB Init"] super[].__init__[] class Children[ParentA, ParentB]: def __init__[self]: print["Children Init"] super[].__init__[] Children[] # >>> Children Init # >>> ParentA Init # >>> ParentB Init # >>> Grandparent Init
7 hiện tại.class Parent: def self_intro[self]: print["This is parent class"] def parent_method[self]: print["This is parent method"] class Children[Parent]: def self_intro[self]: print["This is children class"] def family_intro[self]: self.self_intro[] # Same as Children.self_intro[self] Parent.self_intro[self] c = Children[] c.family_intro[] # >>> This is children class # >>> This is parent class
Cách giải quyết: sử dụng
13 trong class Parent:
def self_intro[self]:
print["This is parent class"]
def parent_method[self]:
print["This is parent method"]
class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
Parent.self_intro[self]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
06. Khi đó chúng ta cần phải thiết kế lại tất cả các phương thức class Parent:
def self_intro[self]:
print["This is parent class"]
def parent_method[self]:
print["This is parent method"]
class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
Parent.self_intro[self]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
06 của tất cả các lớp: sử dụng class Parent:
def self_intro[self]:
print["This is parent class"]
def parent_method[self]:
print["This is parent method"]
class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
Parent.self_intro[self]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
class Parent:
def self_intro[self]:
print["This is parent class"]
def parent_method[self]:
print["This is parent method"]
class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
Parent.self_intro[self]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
13 trong class Parent:
def self_intro[self]:
print["This is parent class"]
def parent_method[self]:
print["This is parent method"]
class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
Parent.self_intro[self]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
06. Khi đó chúng ta cần phải thiết kế lại tất cả các phương thức class Parent:
def self_intro[self]:
print["This is parent class"]
def parent_method[self]:
print["This is parent method"]
class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
Parent.self_intro[self]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
06 của tất cả các lớp:class Grandparent:
def __init__[self, gp_age, **kwargs]:
self.gp_age = gp_age
print[f"Grandparent age: {self.gp_age}"]
class ParentB[Grandparent]:
def __init__[self, pb_age, **kwargs]:
self.pb_age = pb_age
print[f"ParrentB age: {self.pb_age}"]
super[].__init__[**kwargs]
class ParentA[Grandparent]:
def __init__[self, pa_age, **kwargs]:
self.pa_age = pa_age
print[f"ParentA age: {self.pa_age}"]
super[].__init__[**kwargs]
class Children[ParentA, ParentB]:
def __init__[self, c_age, **kwargs]:
self.c_age = c_age
print[f"Children age: {self.c_age}"]
super[].__init__[**kwargs]
Children[c_age="15", pa_age="40", pb_age="45", gp_age="70"]
# >>> Children age: 15
# >>> ParentA age: 40
# >>> ParentB age: 45
# >>> Grandparent age: 70
Code vẫn trả về kết quả như ý nhưng gọn hơn và dễ bảo trì, mở rộng hơn!
Chúng ta vẫn có thể giải quyết trường hợp này bằng cách gọi phương thức khởi tạo trực tiếp nếu bạn đảm bảo không bị ghi đè cho lớp
class Grandparent:
def __init__[self]:
print["Grandparent Init"]
class ParentA[Grandparent]:
def __init__[self]:
print["ParentA Init"]
GrandParent.__init__[self]
class ParentB[Grandparent]:
def __init__[self]:
print["ParentB Init"]
GrandParent.__init__[self]
class Children[ParentA, ParentB]:
def __init__[self]:
print["Children Init"]
ParentA.__init__[self]
ParentB.__init__[self]
Children[]
# >>> Children Init
# >>> ParentA Init
# >>> Grandparent Init
# >>> ParentB Init
# >>> Grandparent Init
1 hoặc việc ghi đè không gây ảnh hưởng gì [nhưng mình vẫn khuyến khích sử dụng class Parent:
def self_intro[self]:
print["This is parent class"]
def parent_method[self]:
print["This is parent method"]
class Children[Parent]:
def self_intro[self]:
print["This is children class"]
def family_intro[self]:
self.self_intro[] # Same as Children.self_intro[self]
Parent.self_intro[self]
c = Children[]
c.family_intro[]
# >>> This is children class
# >>> This is parent class
2 hơn vì lí do bảo trì và mở rộng!]5. Kết bài
Qua bài này mình đã trình bày với các bạn:
- Gọi phương thức từ lớp cha bằng
2 hoặc trực tiếpclass Parent: def self_intro[self]: print["This is parent class"] def parent_method[self]: print["This is parent method"] class Children[Parent]: def self_intro[self]: print["This is children class"] def family_intro[self]: self.self_intro[] # Same as Children.self_intro[self] Parent.self_intro[self] c = Children[] c.family_intro[] # >>> This is children class # >>> This is parent class
- Khái niệm MRO và ý nghĩa tham số của
2class Parent: def self_intro[self]: print["This is parent class"] def parent_method[self]: print["This is parent method"] class Children[Parent]: def self_intro[self]: print["This is children class"] def family_intro[self]: self.self_intro[] # Same as Children.self_intro[self] Parent.self_intro[self] c = Children[] c.family_intro[] # >>> This is children class # >>> This is parent class
- Diamond Problem và cách giải quyết bằng
2class Parent: def self_intro[self]: print["This is parent class"] def parent_method[self]: print["This is parent method"] class Children[Parent]: def self_intro[self]: print["This is children class"] def family_intro[self]: self.self_intro[] # Same as Children.self_intro[self] Parent.self_intro[self] c = Children[] c.family_intro[] # >>> This is children class # >>> This is parent class
Nếu bài viết có chỗ nào không rõ hoặc sai thì xin hãy cho mình biết. Cảm ơn các bạn đã dành thời gian đọc bài viết này!
6. Tham khảo
- What is super[] function? How to use super[] function and a mini problem/solution when use super[] for multiple inheritance
2 Python documentclass Parent: def self_intro[self]: print["This is parent class"] def parent_method[self]: print["This is parent method"] class Children[Parent]: def self_intro[self]: print["This is children class"] def family_intro[self]: self.self_intro[] # Same as Children.self_intro[self] Parent.self_intro[self] c = Children[] c.family_intro[] # >>> This is children class # >>> This is parent class
2 parametersclass Parent: def self_intro[self]: print["This is parent class"] def parent_method[self]: print["This is parent method"] class Children[Parent]: def self_intro[self]: print["This is children class"] def family_intro[self]: self.self_intro[] # Same as Children.self_intro[self] Parent.self_intro[self] c = Children[] c.family_intro[] # >>> This is children class # >>> This is parent class
- Best practice for
2 and how to Incorporate a Non-cooperative Classclass Parent: def self_intro[self]: print["This is parent class"] def parent_method[self]: print["This is parent method"] class Children[Parent]: def self_intro[self]: print["This is children class"] def family_intro[self]: self.self_intro[] # Same as Children.self_intro[self] Parent.self_intro[self] c = Children[] c.family_intro[] # >>> This is children class # >>> This is parent class
- Diamond inheritance problem
- Bound, unbound, and static methods in Python
- Images source: Unsplash