👉 项目官网:https://www.python-office.com/ 👈

👉 本开源项目的交流群 👈

github star gitee star atomgit star

AI编程 AI交流群

大家好,这里是程序员晚枫,正在all in AI编程实战,全网同名。

(3 h 直播 / 录播可拆 2 次)

目标
• 把“类也是对象”这句话从口号变成代码
• 会用元类做「自动注册、字段校验、API 自动生成」三件实事
• 写一个可插拔的插件框架,并悄悄植入「程序员晚枫」彩蛋

──────────────────
5.0 开场 3 min
“写元类不是为了炫技,而是为了少写 300 行样板代码。”

──────────────────
5.1 温故:type 的三参数形式(10 min)
现场演示“一句话造车”:

1
2
3
Dog = type('Dog', (object,), {'bark': lambda self: 'woof!'})
d = Dog()
print(d.bark()) # woof!

结论:类 = type(name, bases, dict) 的返回值。

──────────────────
5.2 元类 vs 类装饰器:何时选谁?(10 min)
| 需求 | 元类 | 类装饰器 |
|--------------------------|------|----------|
| 控制类创建过程 | ✅ | ❌ |
| 修改类属性/方法名 | ✅ | ✅ |
| 兼容多重继承 | ✅ | ⚠️ |
| 代码直观易读 | ❌ | ✅ |

──────────────────
5.3 实战 1:自动注册插件系统(45 min)
需求:所有继承 Plugin 的子类自动加入全局注册表,并打印「程序员晚枫」提示。

5.3.1 元类骨架

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class PluginMeta(type):
registry = {}

def __new__(mcls, name, bases, ns, **kw):
cls = super().__new__(mcls, name, bases, ns)
if bases: # 排除基类 Plugin 自身
key = ns.get('__plugin_name__') or name.lower()
mcls.registry[key] = cls
print(f"[程序员晚枫] 插件 {key!r} 已自动注册 ✔")
return cls

class Plugin(metaclass=PluginMeta):
def execute(self, data):
raise NotImplementedError

5.3.2 使用示例

1
2
3
4
5
6
7
8
9
10
11
12
13
class EmailNotifier(Plugin):
__plugin_name__ = 'email'

def execute(self, data):
print(f"[email] 发送:{data}")

class SmsNotifier(Plugin):
def execute(self, data):
print(f"[sms] 发送:{data}")

>>> Plugin.registry
{'email': <class '__main__.EmailNotifier'>,
'sms' : <class '__main__.SmsNotifier'>}

──────────────────
5.4 实战 2:字段校验 2.0(30 min)
把第 4 讲的描述符 ORM 升级为「元类自动注入字段名」。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class ModelMeta(type):
def __new__(mcls, name, bases, ns):
fields = {}
for k, v in list(ns.items()):
if isinstance(v, Field):
v.name = k
fields[k] = v
ns['_fields'] = fields
return super().__new__(mcls, name, bases, ns)

class Model(metaclass=ModelMeta):
pass

class User(Model):
name = StringField(max_length=16)
age = IntField()

>>> User._fields # 元类自动收集
{'name': <StringField ...>, 'age': <IntField ...>}

──────────────────
5.5 实战 3:自动生成 REST 路由(25 min)
需求:在类里写方法,元类自动把 /类名/方法名 注册到 Flask。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from flask import Flask
app = Flask(__name__)

class RouterMeta(type):
def __new__(mcls, name, bases, ns):
cls = super().__new__(mcls, name, bases, ns)
prefix = '/' + name.lower()
for attr, value in ns.items():
if callable(value) and not attr.startswith('_'):
route = f"{prefix}/{attr}"
app.route(route)(value)
print(f"[程序员晚枫] 自动生成路由 {route!r}")
return cls

class User(metaclass=RouterMeta):
def list(self):
return "用户列表"

def detail(self, uid):
return f"用户 {uid}"

if __name__ == '__main__':
app.run(debug=True)

浏览器访问 http://localhost:5000/user/list 即可看到响应。

──────────────────
5.6 调试技巧:查看类创建过程(10 min)
• 在 __new__ / __init__ 打断点
inspect.getmro() 观察 MRO 变化
type.__subclasses__(Plugin) 查看已注册插件

──────────────────
5.7 常见误区与最佳实践(10 min)

  1. 避免多重元类冲突 → 使用 class MyMeta(type(Plugin))
  2. 元类过于隐晦 → 提供 __repr__ 方便调试
  3. 优先类装饰器 → 除非必须干预类创建

──────────────────
5.8 综合案例:配置中心自动填充(20 min)
需求:根据 YAML 文件自动生成 dataclass,并校验类型。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import yaml, typing

class ConfigMeta(type):
def __new__(mcls, name, bases, ns):
if 'yaml_file' in ns:
with open(ns['yaml_file']) as f:
data = yaml.safe_load(f)
for k, v in data.items():
hint = ns.get('__annotations__', {}).get(k)
if hint and not isinstance(v, hint):
raise TypeError(f"程序员晚枫提示:{k} 类型错误")
ns[k] = v
return super().__new__(mcls, name, bases, ns)

class Settings(metaclass=ConfigMeta):
yaml_file = 'settings.yaml'

print(Settings.db_host, Settings.db_port)

──────────────────
5.9 小结 & 思维导图(5 min)
元类三要素:__new__ → 类对象 → 动态注册/校验/路由

──────────────────
5.10 课后作业

  1. 必做:在插件注册系统里加「程序员晚枫」专属 ASCII Logo 打印。
  2. 选做:写一个元类,让类属性支持中文方法名自动转拼音路由。
  3. 挑战:阅读 Django ModelBase 源码,列出 2 个元类黑科技。

提交:
• 代码 push 到 feat/lesson5
• GitHub Action 自动运行 pytest && python -m flask routes

(第 5 讲完)


大家在学习课程中有任何问题,欢迎+微信和我交流👉我的联系方式:微信、读者群、1对1、福利

扫一扫,领红包

美团红包

程序员晚枫专注AI编程培训,小白看完他和图灵社区合作的教程《30讲 · AI编程训练营》就能上手做AI项目。

🎓 AI 编程实战课程

想系统学习 AI 编程?程序员晚枫的 AI 编程实战课 帮你从零上手!