gpt4 book ai didi

python - 装饰器和全局变量

转载 作者:行者123 更新时间:2023-12-01 02:26:17 29 4
gpt4 key购买 nike

该应用程序有一个模块 A,其中包含一个装饰器,该装饰器将函数添加到 A 中的模块级全局列表中。函数列表用于模块内的其他函数。

A.py

import functools


things = []


def register(func):
@functools.wraps(func)
def inner(*args, **kwargs):
things.append(func)
return func
return inner


@register
def foo():pass


@register
def bar():pass


foo()
bar()

print(things)

该模式已被复制到应用程序的其他部分,因此许多模块包含寄存器函数和模块级别列表。

我想通过在单个位置实现 A.register 来减少重复量,但导入的模块需要有自己的本地函数列表。

我尝试导入A并创建一个提供列表:

B.py

import A

things = []


@A.register
def baz():pass


@A.register
def quux():pass


baz()
quux()

print(things)

但是所有的函数都注册在A.things中:

>>> import A
[<function foo at 0x7f3ecdf466e0>, <function bar at 0x7f3ecdf467d0>]
>>> import B
[]
>>> print A.things
[<function foo at 0x7f3ecdf466e0>, <function bar at 0x7f3ecdf467d0>, <function baz at 0x7f3ecdf46410>, <function quux at 0x7f3ecdf469b0>]

有没有办法单独实现A.register,但让它在导入它的模块中填充列表?那就是

>>> print A.things
[<function foo at 0x7f3ecdf466e0>, <function bar at 0x7f3ecdf467d0>]


>>> print B.things
[<function baz at 0x7f3ecdf46410>, <function quux at 0x7f3ecdf469b0>]

最佳答案

您在模块 A 中确实有一个 register() 函数的实现。
模块 B 中没有变量 things,它[变量]仅属于模块 A。

即使您在模块 B 中使用装饰器,也会附加模块 A 中的变量 things

要记住的另一个非常重要的一点是,每次调用函数时都会附加变量 things

如果您无法在每个模块中更改算法声明变量 事物 并创建一个如下所示的装饰器:

(代码来自ryachza)

def register(things=things):
def _register(func):
@functools.wraps(func)
def inner(*args, **kwargs):
things.append(func)
return func

return inner

return _register

但是,这不是使用装饰器的方式。

您可以在每个模块中创建一个变量 things 并像这样附加它。您不必为此使用装饰器。

things = []


def foo():
pass


things.append(foo)


def bar():
pass


things.append(bar)

foo()
bar()

print(things)

关于python - 装饰器和全局变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47357635/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com