Jak tworzone są klasy Pythona
Proszę zrozumieć type, domyślną metaklasę oraz mechanizmy przechwytywania tworzenia klas.
Jak tworzone są klasy Pythona to bezpłatna lekcja Python Academy na CoddyKit. To lekcja 1 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Python Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Python Academy zawiera 4 lekcji w sumie.
type() to metaklasa
Każda klasa w Pythonie jest instancją type. type sama jest klasą — jest metaklasą wszystkich metaklas.
# These are equivalent:
class Dog:
sound = "woof"
Dog2 = type("Dog2", (), {"sound": "woof"})
print(type(Dog)) # <class 'type'>
print(type(Dog2)) # <class 'type'>Trzyargumentowa forma type()
type(name, bases, namespace) dynamicznie tworzy nową klasę. Dokładnie to samo instrukcje class robią wewnętrznej implementacji.
Animal = type("Animal", (), {"speak": lambda self: "..."})
Dog = type("Dog", (Animal,), {"speak": lambda self: "woof"})
d = Dog()
print(d.speak()) # woofEtapy tworzenia klasy
Gdy Python napotyka instrukcję class: 1) rozwiązuje metaklasę, 2) przygotowuje przestrzeń nazw, 3) wykonuje treść klasy, 4) wywołuje 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) jest metodą klasy metaklasy, która zwraca słownik przestrzeni nazw używany podczas wykonywania treści klasy. Proszę ją nadpisać, aby używać OrderedDict lub niestandardowego mapowania.
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__ a __init__ w type
type.__new__ tworzy obiekt klasy, a type.__init__ go inicjalizuje. W metaklasach proszę nadpisać __new__, aby dostosować proces tworzenia klasy.
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()) # TrueDekoratory klas a metaklasy
Dekoratory klas są stosowane po utworzeniu klasy, natomiast metaklasy kontrolują samo jej tworzenie. W przypadku prostego rozszerzania funkcjonalności preferowane są dekoratory. Metaklas należy używać, gdy konieczne jest modyfikowanie procesu tworzenia klasy.
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__ jest wywoływana na klasie bazowej za każdym razem, gdy definiowana jest klasa pochodna. Jest lekką alternatywą dla metaklas przy dostosowywaniu zachowania klas pochodnych.
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 jest wbudowaną metaklasą, która obsługuje abstrakcyjne klasy bazowe za pomocą @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 classSprawdzanie metaklasy klasy
Proszę użyć type(cls), aby znaleźć metaklasę klasy, oraz cls.__mro__, aby wyświetlić kolejność rozwiązywania metod.
class Meta(type): pass
class Foo(metaclass=Meta): pass
print(type(Foo)) # <class '__main__.Meta'>
print(Foo.__mro__) # (Foo, object)Dziedziczenie metaklas
Metaklasa klasy jest dziedziczona przez jej klasy pochodne. Jeśli dwie klasy bazowe mają różne metaklasy, należy użyć najbardziej pochodnej z nich; w przeciwnym razie wystąpi konflikt.
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'>Kiedy używać metaklas
Metaklas należy używać do automatycznego rejestrowania klas pochodnych, wymuszania niezmienników klas, wykrywania pól ORM, jak w modelu Django, oraz wyznaczania tras w ramach API. W większości przypadków lepiej użyć __init_subclass__ lub dekoratorów klas.
# 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 patternsSzybki test
Co robi wyrażenie type("Dog", (Animal,), {"speak": lambda self: "woof"})?
Podsumowanie
Każda klasa jest instancją type. Proces tworzenia klasy obejmuje: rozwiązanie metaklasy → przygotowanie przestrzeni nazw → wykonanie treści → wywołanie metaklasy. Do prostych punktów rozszerzeń klas pochodnych należy preferować __init_subclass__, a pełnej metaklasy używać tylko wtedy, gdy konieczne jest kontrolowanie samego procesu tworzenia klasy.
Często zadawane pytania
Czy lekcja „Jak tworzone są klasy Pythona” jest bezpłatna?
Tak — pełny tekst „Jak tworzone są klasy Pythona” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Python Academy, przejdź na CoddyKit PRO. Kurs Python Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Jak tworzone są klasy Pythona”?
Proszę zrozumieć type, domyślną metaklasę oraz mechanizmy przechwytywania tworzenia klas. Ćwiczysz Python Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Python Academy?
Nie wymagamy żadnego doświadczenia. Python Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 1 z 4.
Ile czasu zajmuje lekcja „Jak tworzone są klasy Pythona”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Python Academy?
Tak. Każda lekcja Python Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Jak tworzone są klasy Pythona
- Pisanie własnych metaklas
- Deskryptory: __get__, __set__, __delete__
- __slots__ i optymalizacja pamięci