
当使用装饰器时,若内部 wrapper 函数未显式返回被装饰函数的执行结果,python 默认返回 none,从而覆盖原函数的正常返回值。
当使用装饰器时,若内部 wrapper 函数未显式返回被装饰函数的执行结果,python 默认返回 none,从而覆盖原函数的正常返回值。
在 Python 中,装饰器本质是“接收一个函数,返回另一个函数”的高阶函数。常见错误是:在 `wrapper` 内调用了原函数并保存了其返回值,却遗漏了 `return` 语句,导致 `wrapper` 自身隐式返回 `None`——这会彻底掩盖原函数的真实输出。
以下是最小可复现问题的代码及修正对比:
❌ 错误写法(导致返回 None):
def logger_decorator(func):
def wrapper(*args, **kwargs):
print(f"Calling {func.__name__} with {args}")
result = func(*args, **kwargs) # ✅ 执行了原函数,但 ❌ 没有返回 result
return wrapper # ⚠️ wrapper 无返回值 → 默认返回 None
@logger_decorator
def add(x, y):
return x + y
print(add(2, 3)) # 输出:None(而非预期的 5)
✅ 正确写法(显式返回原函数结果):
def logger_decorator(func):
def wrapper(*args, **kwargs):
print(f"Calling {func.__name__} with {args}")
result = func(*args, **kwargs)
return result # ✅ 关键:必须返回原函数的计算结果
return wrapper
@logger_decorator
def add(x, y):
return x + y
print(add(2, 3))
# 输出:
# Calling add with (2, 3)
# 5
⚠️ 注意事项:
- 使用
func.__name__(而非func.name)获取函数名,后者会引发AttributeError; - 若被装饰函数可能抛出异常,建议用
try/finally或try/except确保日志逻辑健壮(如需捕获异常后仍返回结果); - 更规范的装饰器应保留原函数的元信息(如文档字符串、参数签名),推荐使用
functools.wraps:from functools import wraps def logger_decorator(func): @wraps(func) # ✅ 保留 __name__, __doc__ 等属性 def wrapper(*args, **kwargs): print(f"Calling {func.__name__} with {args}") return func(*args, **kwargs) # 可直接 return,无需中间变量 return wrapper
总结:装饰器中的 wrapper 函数必须显式 return 被装饰函数的返回值,否则将统一返回 None。这是 Python 装饰器开发中最常见也最易忽视的逻辑陷阱之一。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











