0Pricing
Python Academy · 课时

Python 类的创建方式

了解 type、默认元类和类创建钩子。

Python 类的创建方式 是 CoddyKit 上的免费 Python Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 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) 会动态创建一个新类。这正是 class 语句在底层执行的操作。

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

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

类创建步骤

当 Python 遇到 class 语句时,会依次执行: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

type 中的 __new__ 与 __init__

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)

元类继承

类的元类会被其子类继承。如果两个基类具有不同的元类,则必须使用派生程度最高的元类,否则会出现 conflict。

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 字段(例如 Django 的模型)以及处理 API 框架路由。对于大多数情况,请改用 __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 导师)并解锁 Python Academy 课程的其余内容,请升级到 CoddyKit PRO。 Python Academy 课程共包含 4 节课。

「Python 类的创建方式」这节课中我会学到什么?

了解 type、默认元类和类创建钩子。 你通过在浏览器中直接运行的动手代码来练习 Python Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Python Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Python Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。

「Python 类的创建方式」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Python Academy 课中编写并运行代码吗?

能。每节 Python Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. Python 类的创建方式
  2. 编写自定义元类
  3. 描述器:__get__、__set__、__delete__
  4. __slots__ 与内存优化
← 返回 Python Academy