如何在我的代码中传递全局调试标志变量;我应该使用argparse吗?

Cra*_*aig 5 python logging globals debug-mode argparse

假设我有一个主程序(test.py)和一个小实用程序(test_utils.py),该程序具有由主程序调用的辅助函数。我想通过传递通过debug_flag读取的布尔值来打开代码中的调试语句argparse

现在,我希望test_utils.py程序中的函数也根据的值打印调试语句debug_flag。我总是可以将其debug_flag作为参数添加到每个函数定义中,test_utils.py并在调用函数时传递参数,但是这里有没有更好的方法,例如制作 debug_flag全局变量?但是,如果我声明debug_flag要从中进行全局化 test.py,将如何将其导入 test_utils.py

这里最优雅/ Pythonic的方法是什么?

test.py:

import argparse
from test_utils import summation

def main():
    args = get_args()
    debug_flag = True if args[debug] == 'True' else False
    print summation(5, 6, 7)

def get_args():
    parser = argparse.ArgumentParser(description='Test program')
    parser.add_argument('-d','--debug', help='Debug True/False', default=False)
    args = vars(parser.parse_args())
    return args
Run Code Online (Sandbox Code Playgroud)

test_utils.py:

from test import debug_flag

def summation(x, y, z):
    if debug_flag:
        print 'I am going to add %s %s and %s' % (x, y, z)
    return x + y + z
Run Code Online (Sandbox Code Playgroud)

EDIT1:要弄清楚-如果我通过argparse传递了调试标志,从而将debug_flag设置为True-它将如何传播到其中的函数test_utils.py

EDIT2:根据@ joran-beasley的建议,这就是我所得到的。

test.py:

import argparse
import logging
from test_utils import summation

def main():
    args = get_args()
    logging.getLogger("my_logger").setLevel(logging.DEBUG if args['debug'] == 'True' else logging.WARNING)
    print summation(5, 6, 7)

def get_args():
    parser = argparse.ArgumentParser(description='Test program')
    parser.add_argument('-d','--debug', help='Debug True/False', required=True)
    args = vars(parser.parse_args())
    return args

main()
Run Code Online (Sandbox Code Playgroud)

test_utils.py

import logging

log = logging.getLogger('my_logger')

def summation(x, y, z):
    log.debug('I am going to add %s %s and %s' % (x, y, z))
    return x + y + z
Run Code Online (Sandbox Code Playgroud)

当我运行test.py时,我得到:

$ python test.py -d True
No handlers could be found for logger "my_logger"
18
Run Code Online (Sandbox Code Playgroud)

Jor*_*ley 5

使用日志

# this logger will always now be logging.DEBUG level
logging.getLogger("my_logger").setLevel(logging.DEBUG if args.debug else logging.WARNING)
Run Code Online (Sandbox Code Playgroud)

然后使用

log = logging.getLogger("my_logger")
...
log.warn("some text that should always be seen!")
log.debug("some debug info!")
Run Code Online (Sandbox Code Playgroud)

然后,您可以执行具有多个日志记录级别的操作

log_level = logging.WARNING
if args.verbose > 0:
   log_level = logging.INFO
elif args.verbose > 3:
   log_level = logging.DEBUG
Run Code Online (Sandbox Code Playgroud)

如果出于某种原因您需要检索 currentEffectiveLogLevel (在大多数情况下您确实不应该......只需log.debug在需要调试级别输出时使用)

logging.getLogger("my_logger").getEffectiveLevel()
Run Code Online (Sandbox Code Playgroud)

[编辑以澄清]

log = logging.getLogger('my_logger')

def summation(x, y, z):
   log.debug('I am going to add %s %s and %s' % (x, y, z)) # will not print if my_logger does not have an effective level of debug
   return x + y + z

print(summation(2, 3, 4))
log.setLevel(logging.DEBUG)
print(summation(4, 5, 6))
Run Code Online (Sandbox Code Playgroud)

或者你可以写一个辅助函数

def is_debug():
    return logging.getLogger("my_logger").getEffectiveLevel() == logging.DEBUG
Run Code Online (Sandbox Code Playgroud)

粗糙的你总是可以做一些可怕的hacky废话也喜欢将它写入一个平面文件并读取它或使用真正的全局变量(比你想象的更难并且需要担心很多边缘情况)