Python Academy · Pelajaran

Cara Kelas Python Dicipta

Fahami type, metakelas lalai dan cangkuk penciptaan kelas.

Pelajaran 1 daripada 413 langkah

Cara Kelas Python Dicipta ialah pelajaran Python Academy percuma di CoddyKit. Ini ialah pelajaran 1 daripada 4. Anda boleh membaca keseluruhan pelajaran di bawah secara percuma — kemudian berlatih secara praktikal dalam pelayar menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Python Academy, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Python Academy merangkumi sejumlah 4 pelajaran.

type() ialah metakelas

Setiap kelas dalam Python ialah instans type. type sendiri ialah kelas — metakelas bagi semua metakelas.

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

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

Bentuk tiga argumen type()

type(name, bases, namespace) mencipta kelas baharu secara dinamik. Inilah yang dilakukan oleh pernyataan class secara dalaman.

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

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

Langkah penciptaan kelas

Apabila Python menemui pernyataan class, Python akan: 1) menentukan metakelas, 2) menyediakan ruang nama, 3) melaksanakan badan kelas, 4) memanggil 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) ialah kaedah kelas pada metakelas yang mengembalikan kamus ruang nama yang digunakan semasa pelaksanaan badan kelas. Gantikannya untuk menggunakan OrderedDict atau pemetaan tersuai.

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__ berbanding __init__ dalam type

type.__new__ mencipta objek kelas; type.__init__ memulakannya. Untuk metakelas, gantikan __new__ bagi menyesuaikan penciptaan kelas.

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

Penghias kelas berbanding metakelas

Penghias kelas digunakan selepas penciptaan; metakelas mengawal proses penciptaan itu sendiri. Untuk penambahan mudah, utamakan penghias. Gunakan metakelas apabila anda perlu mempengaruhi proses penciptaan.

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__ dipanggil pada kelas asas setiap kali subkelas ditakrifkan. Ini ialah alternatif ringan kepada metakelas untuk menyesuaikan tingkah laku subkelas.

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 ialah metakelas terbina dalam yang menggerakkan kelas asas abstrak melalui @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

Memeriksa metakelas sesebuah kelas

Gunakan type(cls) untuk mencari metakelas sesebuah kelas dan cls.__mro__ untuk melihat susunan penyelesaian kaedah.

class Meta(type): pass

class Foo(metaclass=Meta): pass

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

Pewarisan metakelas

Metakelas sesebuah kelas diwarisi oleh subkelasnya. Jika dua kelas asas mempunyai metakelas yang berbeza, metakelas yang paling terbit mesti digunakan, atau konflik akan berlaku.

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'>

Bila hendak menggunakan metakelas

Gunakan metakelas untuk: mendaftarkan subkelas secara automatik, menguatkuasakan invarian kelas, mengesan medan ORM seperti Model Django, dan menghalakan rangka kerja API. Dalam kebanyakan kes, gunakan __init_subclass__ atau penghias kelas sebagai gantinya.

# 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

Semakan pantas

Apakah yang dilakukan oleh type("Dog", (Animal,), {"speak": lambda self: "woof"})?

Imbas kembali

Setiap kelas ialah instans type. Saluran penciptaan kelas: tentukan metakelas → sediakan ruang nama → laksanakan badan → panggil metakelas. Utamakan __init_subclass__ untuk cangkuk subkelas yang mudah; gunakan metakelas penuh hanya apabila anda perlu mengawal penciptaan kelas itu sendiri.

Percuma untuk bermula

Pelajari Python dengan tutor kecerdasan buatan — percuma

Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.

Kursus
76
Pelajaran
320

Soalan Lazim

Adakah pelajaran “Cara Kelas Python Dicipta” percuma?

Ya — teks penuh “Cara Kelas Python Dicipta” boleh dibaca secara percuma di web ini. Untuk berlatih secara interaktif menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7, serta membuka kunci baki kursus Python Academy, tingkat taraf kepada CoddyKit PRO. Kursus Python Academy merangkumi sejumlah 4 pelajaran.

Apakah yang akan saya pelajari dalam “Cara Kelas Python Dicipta”?

Fahami type, metakelas lalai dan cangkuk penciptaan kelas. Anda berlatih Python Academy menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.

Adakah saya memerlukan pengalaman untuk memulakan Python Academy?

Tiada pengalaman terdahulu diperlukan. Pembelajaran Python Academy di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 1 daripada 4.

Berapa lamakah pelajaran “Cara Kelas Python Dicipta” diambil?

Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.

Bolehkah saya menulis dan menjalankan kod dalam pelajaran Python Academy ini?

Ya. Setiap pelajaran Python Academy menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.

Semua pelajaran dalam kursus ini

  1. Cara Kelas Python Dicipta
  2. Menulis Metakelas Tersuai
  3. Penerang: __get__, __set__, __delete__
  4. __slots__ dan Pengoptimuman Memori
← Kembali ke Python Academy