Python Academy · บทเรียน

การสืบทอดหลายแบบและ MRO

ทำความเข้าใจการสืบทอดหลายแบบและ MRO ของ Python (การเรียงเชิงเส้นแบบ C3)

บทเรียน 3 จาก 414 ขั้นตอน

การสืบทอดหลายแบบและ MRO เป็นบทเรียน Python Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Python Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Python Academy มีบทเรียนทั้งหมด 4 บทเรียน

บทนำ

Python รองรับการสืบทอดหลายชั้น ลำดับการค้นหาเมธอด (MRO) กำหนดว่าจะเรียกใช้เมธอดใดเมื่อชื่อซ้ำกัน

ไวยากรณ์การสืบทอดหลายชั้น

class C(A, B): สืบทอดจากทั้ง A และ B ดังนั้น C จึงได้รับเมธอดทั้งหมดจากทั้งสองคลาส
class A:
    def hello(self): return 'A'
class B:
    def world(self): return 'B'
class C(A, B): pass
c = C()
print(c.hello(), c.world())

ลำดับการค้นหาเมธอด (MRO)

MRO กำหนดลำดับการค้นหา C.__mro__ แสดงลำดับเป็น C, A, B, object คลาสแรกที่มีเมธอดตรงกันจะเป็นผู้ชนะ
class A:
    def greet(self): return 'A'
class B:
    def greet(self): return 'B'
class C(A, B): pass
print(C().greet())  # A wins
print(C.__mro__)

การทำให้เป็นเส้นตรงแบบ C3

Python ใช้การทำให้เป็นเส้นตรงแบบ C3 เพื่อคำนวณ MRO โดยรับประกันว่าคลาสลูกจะมาก่อนคลาสแม่ และคลาสฐานหลายคลาสจะเรียงจากซ้ายไปขวา
class A: pass
class B(A): pass
class C(A): pass
class D(B, C): pass
print([c.__name__ for c in D.__mro__])

การสืบทอดแบบเพชร

D(B,C) ซึ่ง B และ C ต่างสืบทอดจาก A คือปัญหาการสืบทอดแบบเพชร C3 ทำให้แน่ใจว่า __init__ ของ A จะถูกเรียกเพียงครั้งเดียว
class A:
    def __init__(self): print('A')
class B(A):
    def __init__(self): super().__init__(); print('B')
class C(A):
    def __init__(self): super().__init__(); print('C')
class D(B, C):
    def __init__(self): super().__init__(); print('D')
D()

มิกซิน

มิกซินคือคลาสที่ออกแบบมาสำหรับการสืบทอดหลายชั้น โดยเพิ่มเมธอดให้คลาสอื่น แต่ไม่ได้ทำหน้าที่เป็นคลาสสมบูรณ์ที่ใช้งานเดี่ยว ๆ
class JSONMixin:
    def to_json(self):
        import json
        return json.dumps(vars(self))
class User(JSONMixin):
    def __init__(self, name, age): self.name,self.age=name,age
print(User('Alice', 30).to_json())

กฎการออกแบบมิกซิน

มิกซินควรไม่กำหนด __init__ ไม่สืบทอดจากคลาสที่ไม่ใช่มิกซิน และทำหน้าที่เพียงอย่างเดียว ควรตั้งชื่อให้ลงท้ายด้วย Mixin
class LoggingMixin:
    def log(self, msg): print(f'[{self.__class__.__name__}] {msg}')
class Service(LoggingMixin):
    def run(self): self.log('running')
Service().run()

super() ในการสืบทอดหลายชั้น

super() จะเรียกใช้คลาสถัดไปใน MRO ซึ่งไม่จำเป็นต้องเป็นคลาสแม่โดยตรง แต่ละคลาสต้องเรียกใช้ super() เพื่อให้การทำงานร่วมกันเป็นไปอย่างถูกต้อง
class Base:
    def action(self): return 'Base'
class A(Base):
    def action(self): return 'A->' + super().action()
class B(Base):
    def action(self): return 'B->' + super().action()
class C(A, B):
    def action(self): return 'C->' + super().action()
print(C().action())

type() สำหรับการสร้างคลาสแบบไดนามิก

type('NewClass', (Base,), {'method': fn}) สร้างคลาสแบบไดนามิก เหมาะสำหรับการเขียนโปรแกรมเชิงเมทา
def hello(self): return 'hello'
MyClass = type('MyClass', (object,), {'hello': hello})
print(MyClass().hello())

การตรวจสอบ MRO

ClassName.__mro__ หรือ inspect.getmro(ClassName) แสดงลำดับการค้นหาเป็นทูเพิลของคลาส
class A: pass
class B(A): pass
class C(B): pass
import inspect
print([c.__name__ for c in inspect.getmro(C)])

เมื่อใดควรหลีกเลี่ยงการสืบทอดหลายชั้น

ลำดับชั้นการสืบทอดหลายชั้นที่ซับซ้อนทำความเข้าใจได้ยาก ควรเลือกใช้การประกอบออบเจ็กต์หรือมิกซินแบบเรียบง่าย แทนลำดับชั้นที่ลึกเกินไป
# Prefer:
class User:
    def __init__(self, name, logger):
        self.name = name
        self.logger = logger  # composition
print('composition preferred')

ตรวจสอบอย่างรวดเร็ว

Python ใช้อัลกอริทึมใดในการคำนวณลำดับการค้นหาเมธอด

ทบทวน

การสืบทอดหลายลำดับชั้น: class C(A, B) การหา MRO ด้วยการทำให้เป็นลำดับเชิงเส้นแบบ C3 จะกำหนดลำดับการค้นหาเมธอด ใช้ mixin เพื่อให้การสืบทอดหลายลำดับชั้นเป็นระเบียบ และ super() จะทำตาม MRO

เรียนรู้ต่อไป

คุณมีความก้าวหน้าอย่างยอดเยี่ยม โปรดเรียนรู้ต่อไปเพื่อทำความเข้าใจแนวคิดถัดไปอย่างเชี่ยวชาญ
เริ่มต้นได้ฟรี

เรียนรู้ Python ด้วย AI tutor — ฟรี

เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป

คอร์ส
76
บทเรียน
320

คำถามที่พบบ่อย

บทเรียน “การสืบทอดหลายแบบและ MRO” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การสืบทอดหลายแบบและ MRO” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Python Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Python Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การสืบทอดหลายแบบและ MRO”

ทำความเข้าใจการสืบทอดหลายแบบและ MRO ของ Python (การเรียงเชิงเส้นแบบ C3) คุณปฏิบัติ Python Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Python Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Python Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน

บทเรียน “การสืบทอดหลายแบบและ MRO” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Python Academy นี้ได้ไหม

ได้ บทเรียน Python Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การสืบทอดแบบเดี่ยว
  2. การเขียนทับเมธอดและ super()
  3. การสืบทอดหลายแบบและ MRO
  4. พหุรูปและการพิมพ์แบบดักไทป์
← กลับไปที่ Python Academy