如何使用装饰器将变量注入作用域?

如何使用装饰器将变量注入作用域?,第1张

如何使用装饰器将变量注入作用域?

你不能 作用域名称(闭包)在编译时确定,不能在运行时添加更多。

您可能希望实现的最好方法是使用函数 自己的 全局名称空间添加 全局 名称: __

def decorator_factory(value):    def msg_decorator(f):        def inner_dec(*args, **kwargs): g = f.__globals__  # use f.func_globals for py < 2.6 sentinel = object() oldvalue = g.get('var', sentinel) g['var'] = value try:     res = f(*args, **kwargs) finally:     if oldvalue is sentinel:         del g['var']     else:         g['var'] = oldvalue return res        return inner_dec    return msg_decorator

f.__globals__
是包装函数的全局名称空间,因此即使装饰器位于其他模块中也可以使用。如果
var
已经定义为全局变量,则将其替换为新值,并在调用函数后恢复全局变量。

之所以可行,是因为在函数中任何未分配给且在周围范围中找不到的名称都被标记为全局名称。

演示:

>>> c = 'Message'>>> @decorator_factory(c)... def msg_printer():...     print var... >>> msg_printer()Message>>> 'var' in globals()False

但是除了修饰,我也可以 直接

var
在全局范围内进行定义。 __

请注意,更改全局变量不是线程安全的,并且对同一模块中其他函数的任何瞬时调用也仍将看到该相同的全局变量。



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5674293.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存