You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中return func与return func()的区别及装饰器实例解析

装饰器中return wrapper()的行为解析

先看你代码里的核心问题:装饰器最后返回的是wrapper()而不是wrapper,这直接导致所有被装饰的函数在脚本加载阶段就被自动执行了,具体原因拆解如下:

1. Python装饰器的执行逻辑

当你用@decorator修饰一个函数时,Python会立刻执行decorator(被装饰函数),并把这个调用的返回值重新赋值给原来的函数名。比如装饰hello函数时,相当于执行了:

hello = decorator(hello)

2. wrapper和wrapper()的本质区别

  • wrapper:是一个未执行的函数对象,代表函数本身,只有被调用时才会执行内部代码;
  • wrapper():是直接调用这个函数,会立刻执行wrapper函数体内的所有代码,并返回函数的执行结果(这里返回的是func()的返回值,也就是被装饰函数的返回值)。

3. 你的代码为什么自动执行所有被装饰函数

在你的装饰器里,最后返回的是wrapper(),这意味着:

  1. 装饰hello函数时,decorator(hello)被调用,内部定义wrapper后,立刻执行wrapper();
  2. wrapper()执行时,先打印Before function.,然后调用func()(也就是原来的hello()),打印hello!,再打印After function.,最后返回hello()的返回值(这里hello()没有return,所以是None);
  3. 这个返回值会被赋值给hello变量,此时hello已经不是原来的函数,而是wrapper()执行后的结果None;
  4. 同理,good_bye、thank_you、thanks_a_lot被装饰时,都会重复这个过程,所以脚本一运行,所有被装饰的函数就被依次执行了一遍。

4. 正确的装饰器写法

如果想让被装饰的函数只有在主动调用时才执行,应该返回wrapper函数对象,而不是调用它:

def decorator(func):
    def wrapper():
        print("Before function.")
        val = func()
        print("After function.")
        return val
    return wrapper  # 此处不要加括号

@decorator
def hello():
    print("hello!")

# 此时需要主动调用hello()才会触发执行
hello()

这样装饰后,hello变量指向的是wrapper函数对象,只有当你调用hello()时,才会触发wrapper的执行,进而调用原来的hello()函数。

内容的提问来源于stack exchange,提问作者phat nhat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 07:52:17