0Pricing
Python Academy · บทเรียน

การสร้างคลาสของ Python

ทำความเข้าใจ type เมตาคลาสเริ่มต้น และฮุกการสร้างคลาส

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

type() คือเมตาคลาส

ทุกคลาสใน Python เป็นอินสแตนซ์ของ type โดย type เองก็เป็นคลาส และเป็นเมตาคลาสของเมตาคลาสทั้งหมด

# These are equivalent:
class Dog:
    sound = "woof"

Dog2 = type("Dog2", (), {"sound": "woof"})
print(type(Dog))    # <class 'type'>
print(type(Dog2))   # <class 'type'>

รูปแบบสามอาร์กิวเมนต์ของ type()

type(name, bases, namespace) สร้างคลาสใหม่แบบไดนามิก ซึ่งเป็นสิ่งเดียวกับที่คำสั่งประกาศคลาสทำอยู่เบื้องหลัง

Animal = type("Animal", (), {"speak": lambda self: "..."})
Dog = type("Dog", (Animal,), {"speak": lambda self: "woof"})

d = Dog()
print(d.speak())   # woof

ขั้นตอนการสร้างคลาส

เมื่อ Python พบคำสั่งประกาศคลาส จะดำเนินการดังนี้ 1) แก้ไขเมตาคลาส 2) เตรียมเนมสเปซ 3) ดำเนินการเนื้อหาของคลาส 4) เรียก metaclass(name, bases, namespace)

# class Foo(Base, metaclass=Meta):
#   x = 1
#
# Equivalent to:
# namespace = Meta.__prepare__("Foo", (Base,))
# exec(class_body, namespace)
# Foo = Meta("Foo", (Base,), namespace)

__prepare__

__prepare__(name, bases, **kw) เป็นเมธอดของคลาสบนเมตาคลาส ซึ่งคืนค่าดิกชันนารีเนมสเปซที่ใช้ระหว่างดำเนินการเนื้อหาของคลาส คุณสามารถเขียนทับเมธอดนี้เพื่อใช้ OrderedDict หรือการแมปแบบกำหนดเองได้

class OrderedMeta(type):
    @classmethod
    def __prepare__(mcs, name, bases, **kw):
        print(f"Preparing namespace for {name}")
        return {}

class MyClass(metaclass=OrderedMeta):
    x = 1
    y = 2

__new__ เทียบกับ __init__ ใน type

type.__new__ สร้างอ็อบเจ็กต์คลาส ส่วน type.__init__ เริ่มต้นการทำงานของอ็อบเจ็กต์นั้น สำหรับเมตาคลาส ให้เขียนทับ __new__ เพื่อปรับแต่งการสร้างคลาส

class Singleton(type):
    _instances = {}

    def __call__(cls, *args, **kw):
        if cls not in cls._instances:
            cls._instances[cls] = super().__call__(*args, **kw)
        return cls._instances[cls]

class DB(metaclass=Singleton):
    pass

print(DB() is DB())  # True

ตัวตกแต่งคลาสเทียบกับเมตาคลาส

ตัวตกแต่งคลาสทำงานหลังการสร้างคลาส ส่วนเมตาคลาสควบคุมกระบวนการสร้างเอง หากต้องการเพิ่มความสามารถอย่างง่าย ให้เลือกใช้ตัวตกแต่ง แต่ให้ใช้เมตาคลาสเมื่อจำเป็นต้องเปลี่ยนแปลงกระบวนการสร้าง

def add_repr(cls):
    cls.__repr__ = lambda self: f"{cls.__name__}()"
    return cls

@add_repr
class Widget:
    pass

print(Widget())  # Widget()

__init_subclass__

__init_subclass__ จะถูกเรียกบนคลาสฐานทุกครั้งที่มีการกำหนดคลาสย่อย เป็นทางเลือกที่มีน้ำหนักเบากว่าเมตาคลาสสำหรับปรับแต่งการทำงานของคลาสย่อย

class Plugin:
    _registry = []

    def __init_subclass__(cls, **kw):
        super().__init_subclass__(**kw)
        Plugin._registry.append(cls)

class AudioPlugin(Plugin): pass
class VideoPlugin(Plugin): pass

print(Plugin._registry)  # [AudioPlugin, VideoPlugin]

ABCMeta

ABCMeta เป็นเมตาคลาสในตัวที่ทำให้คลาสฐานนามธรรมทำงานผ่าน @abstractmethod

from abc import ABCMeta, abstractmethod

class Shape(metaclass=ABCMeta):
    @abstractmethod
    def area(self): ...

class Circle(Shape):
    def __init__(self, r): self.r = r
    def area(self): return 3.14159 * self.r ** 2

# Shape()  # TypeError: Can't instantiate abstract class

การตรวจสอบเมตาคลาสของคลาส

ใช้ type(cls) เพื่อค้นหาเมตาคลาสของคลาส และใช้ cls.__mro__ เพื่อดูลำดับการค้นหาเมธอด

class Meta(type): pass

class Foo(metaclass=Meta): pass

print(type(Foo))       # <class '__main__.Meta'>
print(Foo.__mro__)     # (Foo, object)

การสืบทอดเมตาคลาส

เมตาคลาสของคลาสจะถูกสืบทอดไปยังคลาสย่อย หากคลาสฐานสองคลาสมีเมตาคลาสแตกต่างกัน จะต้องใช้เมตาคลาสที่สืบทอดลงมามากที่สุด มิฉะนั้นจะเกิดข้อขัดแย้ง

class MyMeta(type): pass

class Base(metaclass=MyMeta): pass
class Child(Base): pass   # Child's metaclass is also MyMeta

print(type(Child))   # <class '__main__.MyMeta'>

ควรใช้เมตาคลาสเมื่อใด

ใช้เมตาคลาสสำหรับการลงทะเบียนคลาสย่อยโดยอัตโนมัติ การบังคับใช้เงื่อนไขคงที่ของคลาส การตรวจจับฟิลด์ของ ORM เช่น Model ของ Django และการกำหนดเส้นทางของเฟรมเวิร์กส่วนเชื่อมต่อโปรแกรมประยุกต์ ในกรณีส่วนใหญ่ ให้ใช้ __init_subclass__ หรือตัวตกแต่งคลาสแทน

# Real-world: Django ORM uses ModelBase metaclass
# to collect field definitions into _meta

# You rarely need a custom metaclass;
# __init_subclass__ covers most plugin/registration patterns

ตรวจสอบความเข้าใจอย่างรวดเร็ว

type("Dog", (Animal,), {"speak": lambda self: "woof"}) ทำอะไร

สรุปทบทวน

ทุกคลาสเป็นอินสแตนซ์ของ type กระบวนการสร้างคลาสมีดังนี้ แก้ไขเมตาคลาส → เตรียมเนมสเปซ → ดำเนินการเนื้อหา → เรียกเมตาคลาส เลือกใช้ __init_subclass__ สำหรับจุดเชื่อมต่อของคลาสย่อยอย่างง่าย และใช้เมตาคลาสเต็มรูปแบบเฉพาะเมื่อต้องควบคุมการสร้างคลาสเอง

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

บทเรียน “การสร้างคลาสของ Python” ฟรีหรือไม่

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

คุณจะเรียนรู้อะไรในบทเรียน “การสร้างคลาสของ Python”

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

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

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

บทเรียน “การสร้างคลาสของ Python” ใช้เวลานานแค่ไหน

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

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

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

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

  1. การสร้างคลาสของ Python
  2. การเขียนเมตาคลาสแบบกำหนดเอง
  3. ตัวบอกคุณสมบัติ: __get__, __set__, __delete__
  4. __slots__ และการเพิ่มประสิทธิภาพหน่วยความจำ
← กลับไปที่ Python Academy