钩子函数(Hook)= 框架 / 类里提前留好的 “空位函数”
一句话说清:钩子函数(Hook)= 框架/类里提前留好的“空位函数”,你填上自己的代码,它就会在特定时机自动执行,不用改框架源码。
下面用最直白的讲法 + Python 小例子,把概念、作用、和普通函数/方法的区别都讲清楚。
一、通俗理解(必懂)
想象你买了一个衣柜(框架/类):
- 衣柜本身做好了(主流程固定)
- 但它留了几个挂钩(钩子函数),平时空着
- 你可以挂自己的衣服(写自定义函数)
- 衣柜开门/关门时,自动帮你把挂钩上的衣服“执行”一遍
专业点:
- 钩子 = 预留扩展点
- 你写的函数 = 挂上去的自定义逻辑
- 触发时机 = 框架走到某步自动调用
二、和普通函数、方法的区别
先回顾你刚学的:
- 函数:独立,自己调用自己
- 方法:在类里,对象调用
- 钩子函数:框架留好的方法/空位,你重写,框架自动调用
对比表:
| 概念 | 谁定义 | 谁调用 | 目的 |
|---|---|---|---|
| 普通函数 | 你 | 你 | 自己用 |
| 普通方法 | 类 | 对象 | 类的行为 |
| 钩子函数 | 框架/父类 | 框架/父类 | 扩展、定制 |
三、Python 最简例子(一看就懂)
场景:框架主流程固定,留钩子让你扩展
# 框架(父类)——写死的主流程
class Framework:
# 钩子:空方法,留给你重写
def before_run(self):
pass # 默认啥也不干
# 主流程(固定)
def run(self):
print("=== 开始运行 ===")
self.before_run() # 框架自动调用钩子
print("=== 运行中 ===")
# 你的代码(子类)——重写钩子
class MyCode(Framework):
# 实现钩子:插入自己逻辑
def before_run(self):
print("[钩子触发] 我在运行前先打个日志/初始化")
# 使用
obj = MyCode()
obj.run()
输出:
=== 开始运行 ===
[钩子触发] 我在运行前先打个日志/初始化
=== 运行中 ===
关键点:
before_run就是钩子- 你没改 Framework 源码,只重写了钩子
- 框架走到
self.before_run()时自动调用你的代码
四、Python 里常见的钩子
-
魔法方法(最常见)
__init__、__str__、__call__等,Python 内置流程自动调用。class A: def __str__(self): # 钩子:print时自动调用 return "我是钩子" print(A()) # 输出:我是钩子 -
框架钩子
- Django:
save()前后的pre_save/post_save - Scrapy:
process_request/process_response - Pytest:
pytest_runtest_makereport
- Django:
-
requests 库钩子(实战常用)
import requests def after_response(response, *args, **kwargs): print("状态码:", response.status_code) # 自定义逻辑 # 注册钩子:请求完成后自动执行 requests.get("https://www.baidu.com", hooks={"response": after_response})
五、一句话总结
- 普通函数:你写,你调
- 普通方法:类写,对象调
- 钩子函数:框架留,你写,框架自动调
- 核心价值:不改源码,扩展功能(开闭原则)
要不要我给你写一个带钩子的完整小项目(比如简易爬虫框架),你直接运行就能看到钩子怎么工作?
浙公网安备 33010602011771号