可能使用装饰器猴子修补全局变量吗?
作者:互联网
猴子可以修补全局变量吗?
就我而言,我将全局变量设置为整个文件的默认记录器,但是对于某些特殊功能,我将使用装饰器来更改记录器并添加一些其他信息.
如以下代码:
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()的日志不会转到logger导入,而不会转到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()
因此,如何使用装饰器来修补全局变量.
解决方法:
您可以临时更改函数全局变量:
_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
这不是线程安全的;您不仅要更改此函数的全局变量,还要更改整个模块的全局变量.
标签:monkeypatching,python 来源: https://codeday.me/bug/20191120/2041706.html