我有以下应用程序结构:
./utils.py
def do_something(logger=None):
if not logger:
logger = logging.getLogger(__name__)
print('hello')
logger.debug('test')
./one.py
from utils import do_something
logger = logging.getLogger(__name__)
do_something(logger=logger)
./two.py
from utils import do_something
logger = logging.getLogger(__name__)
do_something(logger=logger)
现在运行,日志输出将显示使用函数(one
和two
)而不是utils
的相应模块的名称。然后,我使用此信息(记录器的名称)来过滤消息。
有没有办法做到这一点,而不必通过记录器作为参数?我是否必须基本上反省调用函数并基于此初始化记录器?这种配方的常见解决方案是什么,当在整个代码库中使用一个函数但是记录器应该是那些调用函数的函数?
答案 0 :(得分:1)
变量do_something()
是全局的,可以从logger = logging.getLogger(__name__)
def do_something():
x = logger
函数内部访问,如下所示:
logger
仔细阅读后:
当一种功能时,这种配方的常见解决方案是什么 在整个代码库中使用,但记录器应该是那些 调用函数?
在simple english中会是:
如何从导入的函数
do_something()
访问全局变量from utils import do_something logger = logging.getLogger(__name__) do_something() # logger global is not visible in do_something() do_something(logger=logger) # the only way
?
我的结论是没有别的办法! 您必须将记录器作为此特定情况的参数传递。
{{1}}
答案 1 :(得分:1)
传递logger
作为参数对我来说很好。但是如果你有多次调用do_something
,那么在每次调用中传递相同的记录器不仅太冗长而且容易出错 - 你可能会错误地传递错误的记录器。此外,虽然你确实需要让do_something
知道记录器,但是在你调用它的时候这样做可能没有意义 - 你想要做一些事情,而不是弄乱记录器。 OOP救援:使do_something
成为类的方法,并在实例化类时传递记录器,然后您不需要将它传递给方法。
# utils.py
class UsefulObject:
def __init__(self, logger):
self._logger = logger
def do_something(self):
print('hello')
self._logger.debug('test')
现在,在客户端模块中,您可以创建UsefulObject
的实例,并且可以在其上调用.do_something
,而无需每次都传递记录器。
# one.py
from utils import UsefulObject
logger = logging.getLogger(__name__)
useful_object = UsefulObject(logger) # do this once
# ...
useful_object.do_something() # do this many times, do not pass the logger
答案 2 :(得分:0)
如果您不喜欢现有的解决方案,这是一种神奇的方法:
def do_something():
logger = inspect.currentframe().f_back.f_globals['log']
...
然后,调用函数必须具有一个名为log
的全局变量。