一开始感觉有点难理解,不知道为啥,但是看了这段代码就秒懂了。
这就是一个简单的装饰器的例子:说白了就是在装饰器里新建了一个新函数,新函数会调用老函数,但是会自己装饰一些内容。最后返回这个新函数替代老函数的返回。
python
def decorator(old_func):
def new_func():
print("调用前")
old_func()
print("调用后")
return new_func
含义是:
decorator(old_func):接收旧函数
new_func():定义一个新函数
old_func():在新函数里面调用旧函数
return new_func:把新函数返回出去,替换原来的函数名
所以之后:
python
@decorator
def hello():
print("hello")
等价于:
python
def hello():
print("hello")
hello = decorator(hello)
最后 hello() 实际执行的是 new_func():
调用前
hello
调用后
不过注意:不是所有装饰器都必须这么写。
有些装饰器只是做"注册",然后原样返回旧函数:
python
def decorator(old_func):
registry.append(old_func)
return old_func
这种没有新函数包装,只是把函数登记一下。
有个很好的例子:(下面没有过多的装饰,只是把老函数注册到了一个字典)
python
class A2AServer:
def __init__(self):
self.skills = {} # 存放所有技能
def skill(self, name):
# 这一层接收技能名称(如 "multiply"),返回一个装饰器函数
def decorator(func):
# 这一层接收你写的函数,把它注册到 skills 字典里
self.skills[name] = func
print(f"✅ 技能 '{name}' 注册成功")
return func # 这里原样返回你的函数
return decorator
# 现在你就能用上面那种写法了
calculator = A2AServer()
@calculator.skill("multiply")
def multiply_numbers(query):
return "计算结果..."
# 检查是否注册成功
print(calculator.skills) # {'multiply': <function multiply_numbers ...>}
Python 解释器看到 @,知道要执行:
python
multiply_numbers = calculator.skill("multiply")(multiply_numbers)
第三步:calculator.skill("multiply")
调用 skill 方法,传入 "multiply":
python
def skill(self, name): # name = "multiply"
def decorator(func): # 还没执行,只是定义了内部函数
self.skills[name] = func
print(f"✅ 技能 '{name}' 注册成功")
return func
return decorator # 返回 decorator 这个函数本身
calculator.skill("multiply") 的返回值是 decorator 这个函数。
此时代码等价于:
python
multiply_numbers = decorator(multiply_numbers)
第四步:decorator(multiply_numbers)
把 multiply_numbers 这个函数作为参数,调用 decorator:
python
def decorator(func): # func = multiply_numbers 这个函数
self.skills[name] = func # self.skills["multiply"] = multiply_numbers
print(f"✅ 技能 '{name}' 注册成功") # 输出: ✅ 技能 'multiply' 注册成功
return func # 返回 multiply_numbers 本身
decorator 做了两件事:
-
把
multiply_numbers存进calculator.skills["multiply"] -
把
multiply_numbers原样返回
第五步:multiply_numbers = decorator(multiply_numbers)
decorator 返回了 multiply_numbers 本身,又赋值给 multiply_numbers。
所以 multiply_numbers 还是原来的函数,没有变。 只是在这个过程中被"注册"到了 calculator.skills 字典里。
【定义阶段,代码加载时】
- calculator = A2AServer()
→ calculator.skills = {}
- @calculator.skill("multiply")
→ 调用 calculator.skill("multiply")
→ 返回 decorator 函数
→ 调用 decorator(multiply_numbers)
→ self.skills["multiply"] = multiply_numbers
→ 输出: ✅ 技能 'multiply' 注册成功
→ 返回 multiply_numbers
→ multiply_numbers = multiply_numbers(不变)
- print(calculator.skills)
→ 输出: {'multiply': <function multiply_numbers at 0x...>}