您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

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

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

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

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

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在全局范围内进行定义。 __

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

其他 2022/1/1 18:30:11 有415人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶