装饰器:了解为什么不刷新局部变量

丹尼尔451

我写了一个简单的装饰器:

from functools import wraps
import random

def my_dec(f):
    lst = list()

    @wraps(f)
    def wrapper(*args):
        lst.append(random.randint(0, 9))
        print(lst)
        return f(*args)

    return wrapper

@my_dec
def foo():
    print("foo called")

现在,如果我foo多次拨打电话lst则不会被刷新。相反,它会随着时间的推移而累积。因此,多次调用fooreturn将返回如下输出:

foo()
> [4]
> foo called

foo()
> [4, 9]
> foo called

foo()
> [4, 9, 1]
> foo called

...

这是为什么?我以为decorator是语法糖my_dec(foo)吗?!我以为每次对my_decflush的调用lst

米吉尔森

您说得对...装饰器只是语法糖。具体来说:

@decorator
def foo():
    pass

与以下内容完全相同

def foo():
    pass
foo = decorator(foo)

让我们多了几分古怪和重写这个法子是大多相当于1

def bar():
    pass
foo = decorator(bar)
del bar

希望以这种方式写出来,您可以看到,如果我打电话foo很多次,我就不会打电话decorator很多次。decorator仅被调用一次(以帮助创建foo)。

现在在您的示例中,装饰器在被调用时立即创建一个列表:

def my_dec(f):
    lst = list()  # list created here!

    @wraps(f)
    def wrapper(*args):
        lst.append(random.randint(0, 9))
        print(lst)
        return f(*args)

    return wrapper

返回的函数wrapper将分配给您foo,因此调用时即foo在调用wrapper请注意,没有代码wrapper可以重置lst-仅代码会添加更多元素,lst因此这里没有任何内容表明调用之间lst 应该“清除”。

1(取决于装饰器的功能,您可能会在函数的__name__属性中看到一些差异,但否则是同一回事...)


还要注意,lst每次调用装饰器时,您都会得到一个如果我们喜欢并装饰foo两次,我们可以为之疯狂

@my_dec
@my_dec
def foo():
    pass

或者,我们可以装饰多个功能:

@my_dec
def foo():
    pass

@my_dec
def bar():
    pass

然后,当我们调用fooand时bar,我们将看到它们各自积累了自己的(不同的)随机数列表。换句话说,每次将装饰器应用于某物时,都会创建一个新列表,并且每次调用“某物”时,该列表都会增长。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

为什么解释器调用变量ia局部变量

来自分类Dev

为什么局部变量不超出范围?

来自分类Dev

了解局部变量的垃圾收集器行为

来自分类Dev

为什么在未使用的局部变量上没有得到编译器错误?

来自分类Dev

C Keil编译器将malloc用于局部变量,为什么?

来自分类Dev

为什么打字稿使用angular编译掉我的基本控制器的局部变量?

来自分类Dev

为什么Java默认只初始化类变量而不初始化局部变量?

来自分类Dev

为什么局部变量未设置为零?

来自分类Dev

为什么要保留局部变量的堆栈空间?

来自分类Dev

为什么要使用局部变量指针?

来自分类Dev

为什么局部变量会在Python中循环

来自分类Dev

为什么局部变量初始化为零

来自分类Dev

为什么我的局部变量没有被覆盖?

来自分类Dev

为什么要保留局部变量的堆栈空间?

来自分类Dev

为什么此局部变量声明不起作用?

来自分类Dev

为什么分配的局部变量变为空

来自分类Dev

为什么我的局部变量为null?

来自分类Dev

为什么局部变量会自动更改

来自分类Dev

局部变量的内存被重新分配 - 为什么

来自分类Dev

CppUnit:为什么静态局部变量保持其值?

来自分类Dev

为什么局部变量会自我更新?

来自分类Dev

为什么 printf 会修改以前的局部变量?

来自分类Dev

为什么我得到“赋值前引用的局部变量”?

来自分类Dev

为什么不能在声明局部变量之前不像静态变量那样初始化局部变量?

来自分类Dev

了解python装饰器。为什么这不起作用?

来自分类Dev

节点模块局部变量不持久

来自分类Dev

为什么在类中定义的变量不是局部变量而是Java中的实例变量?

来自分类Dev

为什么在类中定义的变量不是局部变量而是Java中的实例变量?

来自分类Dev

为什么局部变量没有默认类型而全局变量在C中呢?

Related 相关文章

  1. 1

    为什么解释器调用变量ia局部变量

  2. 2

    为什么局部变量不超出范围?

  3. 3

    了解局部变量的垃圾收集器行为

  4. 4

    为什么在未使用的局部变量上没有得到编译器错误?

  5. 5

    C Keil编译器将malloc用于局部变量,为什么?

  6. 6

    为什么打字稿使用angular编译掉我的基本控制器的局部变量?

  7. 7

    为什么Java默认只初始化类变量而不初始化局部变量?

  8. 8

    为什么局部变量未设置为零?

  9. 9

    为什么要保留局部变量的堆栈空间?

  10. 10

    为什么要使用局部变量指针?

  11. 11

    为什么局部变量会在Python中循环

  12. 12

    为什么局部变量初始化为零

  13. 13

    为什么我的局部变量没有被覆盖?

  14. 14

    为什么要保留局部变量的堆栈空间?

  15. 15

    为什么此局部变量声明不起作用?

  16. 16

    为什么分配的局部变量变为空

  17. 17

    为什么我的局部变量为null?

  18. 18

    为什么局部变量会自动更改

  19. 19

    局部变量的内存被重新分配 - 为什么

  20. 20

    CppUnit:为什么静态局部变量保持其值?

  21. 21

    为什么局部变量会自我更新?

  22. 22

    为什么 printf 会修改以前的局部变量?

  23. 23

    为什么我得到“赋值前引用的局部变量”?

  24. 24

    为什么不能在声明局部变量之前不像静态变量那样初始化局部变量?

  25. 25

    了解python装饰器。为什么这不起作用?

  26. 26

    节点模块局部变量不持久

  27. 27

    为什么在类中定义的变量不是局部变量而是Java中的实例变量?

  28. 28

    为什么在类中定义的变量不是局部变量而是Java中的实例变量?

  29. 29

    为什么局部变量没有默认类型而全局变量在C中呢?

热门标签

归档