可以修补全局变量吗?
对于我的情况,我将一个全局变量设置为整个文件的默认记录器,但是对于某些特殊功能,我会使用装饰器来更改记录器并添加一些额外的信息。
如下面的代码:
libmonkey.py
logger = logging.getLogger(__name__)
@change_logger('import')
def do_some():
logger.debug('This is a debug')
#do some things
def do_some2():
logger.debug('This is a debug')
#do some things
decorator.py
def change_logger(name):
def decorator(func):
@functools.wraps(func)
def wrapper(*arg, **kwargs):
logger = logging.getLogger(name)
func(*arg, **kwargs)
return wrapper
return decorator
当我按照代码操作时,do_some()
的日志不会转到记录器import
而不是libmonkey
from libmonkey import do_some, do_some2
#skip code for set logging lvl to debug, and output logging to stream.
do_some()
do_some2()
那么如何使用装饰器来修补全局变量。
答案 0 :(得分:3)
您可以暂时更改函数全局变量:
_sentinel = object()
def change_logger(name):
def decorator(func):
@functools.wraps(func)
def wrapper(*arg, **kwargs):
old_logger = func.__globals__.get('logger', _sentinel)
func.__globals__['logger'] = logging.getLogger(name)
try:
result = func(*arg, **kwargs)
finally:
if old_logger is not _sentinel:
func.__globals__['logger'] = old_logger
else:
del func.__globals__['logger']
return result
return wrapper
return decorator
这不线程安全;你正在改变全局变量,不只是为了这个函数而是整个模块。