你不能 作用域名称(闭包)在编译时确定,不能在运行时添加更多。
您可能希望实现的最好方法是使用函数 自己的 全局名称空间添加 全局 名称: __
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
在全局范围内进行定义。 __