装饰器
2026/7/23大约 2 分钟
在 Python 中,装饰器 (Decorator) 是一种极具艺术感的语法。
简单来说,装饰器就是一个**“包装盒”。它可以在不修改原函数代码的情况下,给函数增加额外功能**(比如:记录日志、计时、权限检查等)。
对于你正在开发的 Agent 来说,装饰器非常关键,因为很多框架(如 smolagents 或 OpenClaw)都用它来一键将普通函数转变为 AI 工具。
1. 形象理解:装饰器是什么?
想象你有一个“裸机”函数,它只能执行简单的逻辑。
- 装饰器就像是一套钢铁侠战衣。
- 你把战衣套在“裸机”函数上,函数就瞬间获得了“飞行”和“激光”的能力,但函数内部的逻辑(托尼·史塔克本人)并没有改变。
2. 基础语法:如何写一个装饰器?
装饰器的本质是一个闭包:一个函数返回另一个函数。
Python
# 1. 定义装饰器
def my_decorator(func):
def wrapper():
print("--- 执行前:检查系统权限 ---")
func() # 运行原函数
print("--- 执行后:记录操作日志 ---")
return wrapper
# 2. 使用装饰器 (用 @ 符号)
@my_decorator
def say_hello():
print("正在执行核心业务:Hello Agent!")
# 3. 调用
say_hello()
3. 进阶:带参数的装饰器(最常用)
在实际开发中,你的函数通常是有参数的(比如查询某个特定的 Topic)。这时需要用到 *args 和 **kwargs:
Python
def log_tool_call(func):
def wrapper(*args, **kwargs):
print(f"正在调用工具: {func.__name__},参数为: {args} {kwargs}")
result = func(*args, **kwargs)
print(f"调用结束,结果为: {result}")
return result
return wrapper
@log_tool_call
def query_kafka(topic, lines=10):
return f"从 {topic} 读取了 {lines} 行日志"
# 调用时,会自动打印日志
query_kafka("order-service", lines=5)
4. 为什么 Agent 开发离不开装饰器?
在你计划的 第三阶段(轻量级工具链) 中,你会看到类似这样的写法:
Python
@tool
def get_weather(city: str):
"""获取指定城市的天气。"""
# 你的逻辑
return "晴天"
这个 @tool 装饰器在背后帮你做了三件极其繁琐的事:
- 自动提取:它读取函数的名称
get_weather。 - 自动生成 Schema:它把你的文档字符串(Docstring)提取出来,直接转成 JSON Schema 里的
description。 - 类型检查:它根据
city: str自动生成 Schema 里的type: "string"。
这就是为什么用了装饰器,你就不用手写那几百行枯燥的 JSON 了。
5. 总结:装饰器的三步走
- 定义:写一个接收函数并返回新函数的“外壳”。
- 套用:在目标函数上方写上
@装饰器名。 - 执行:像平常一样调用原函数,它会自动带上“外壳”里的功能。
