Python 如何在脚本中实现--verbose或-v选项?
我从几个工具中了解了Python 如何在脚本中实现--verbose或-v选项?,python,option,Python,Option,我从几个工具中了解了--verbose或-v,我想在我自己的一些脚本和工具中实现这一点 我想把: if verbose: print ... 通过我的源代码,这样,如果用户通过-v选项,变量verbose将设置为True,并打印文本 这是正确的方法还是有更普遍的方法 另外:我不是在寻求一种实现参数解析的方法。我知道这是怎么做的。我只对verbose选项特别感兴趣。如果您有一个函数,比如称为vprint,可以为您检查verbose标志,那么它可能会更干净。然后,您只需调用自己的vprin
--verbose
或-v
,我想在我自己的一些脚本和工具中实现这一点
我想把:
if verbose:
print ...
通过我的源代码,这样,如果用户通过-v
选项,变量verbose
将设置为True
,并打印文本
这是正确的方法还是有更普遍的方法
另外:我不是在寻求一种实现参数解析的方法。我知道这是怎么做的。我只对verbose选项特别感兴趣。如果您有一个函数,比如称为
vprint
,可以为您检查verbose标志,那么它可能会更干净。然后,您只需调用自己的vprint
函数,您可以在任何需要可选详细信息的地方调用该函数。我的建议是使用函数。但是,与其将if
放入函数中(您可能会尝试这样做),不如这样做:
if verbose:
def verboseprint(*args):
# Print each argument separately so caller doesn't need to
# stuff everything to be printed into a single string
for arg in args:
print arg,
print
else:
verboseprint = lambda *a: None # do-nothing function
% python verbose-tester.py -v
ERROR message
% python verbose=tester.py -vv
WARN message
ERROR message
% python verbose-tester.py -vvv
INFO message
WARN message
ERROR message
if VERBOSE:
def verboseprint(*args, **kwargs):
print(*args, **kwargs)
else:
verboseprint = lambda *a, **k: None # do-nothing function
(是的,您可以在if
语句中定义函数,并且只有在条件为true时才能定义该函数!)
如果您使用的是Python 3,print
已经是一个函数(或者如果您愿意使用print
作为2.x中的一个函数,使用from uuuu future\uuuuuuu导入print\u函数
),则更简单:
verboseprint = print if verbose else lambda *a, **k: None
这样,函数被定义为关闭冗余模式(使用lambda)时不执行任何操作,而不是不断测试verbose
标志
如果用户可以在程序运行期间更改详细模式,这将是错误的方法(您需要函数中的If
),但由于您使用命令行标志设置它,因此您只需要做出一次决定
然后,当您想要打印“verbose”消息时,可以使用例如
verboseprint(“查看我所有的详细信息!”,object(),3)
。我在脚本中所做的是在运行时检查是否设置了“verbose”选项,然后将日志记录级别设置为debug。如果未设置,则将其设置为“信息”。这样,您的代码中就不会出现“if verbose”检查 构建和简化@kindall的答案,以下是我通常使用的:
v_print = None
def main()
parser = argparse.ArgumentParser()
parser.add_argument('-v', '--verbosity', action="count",
help="increase output verbosity (e.g., -vv is more than -v)")
args = parser.parse_args()
if args.verbosity:
def _v_print(*verb_args):
if verb_args[0] > (3 - args.verbosity):
print verb_args[1]
else:
_v_print = lambda *a: None # do-nothing function
global v_print
v_print = _v_print
if __name__ == '__main__':
main()
然后在整个脚本中提供以下用法:
v_print(1, "INFO message")
v_print(2, "WARN message")
v_print(3, "ERROR message")
您的脚本可以这样调用:
if verbose:
def verboseprint(*args):
# Print each argument separately so caller doesn't need to
# stuff everything to be printed into a single string
for arg in args:
print arg,
print
else:
verboseprint = lambda *a: None # do-nothing function
% python verbose-tester.py -v
ERROR message
% python verbose=tester.py -vv
WARN message
ERROR message
% python verbose-tester.py -vvv
INFO message
WARN message
ERROR message
if VERBOSE:
def verboseprint(*args, **kwargs):
print(*args, **kwargs)
else:
verboseprint = lambda *a, **k: None # do-nothing function
几点注意:
3
,为您的日志设置了上限,但为了简单起见,我接受这一点v_print
,则必须使用全局打印。这一点都不好玩,但我要挑战别人找到更好的方法使用
日志记录
模块:
将日志记录作为日志导入
…
args=p.parse_args()
如果args.verbose:
log.basicConfig(format=“%(levelname)s:%(message)s”,level=log.DEBUG)
log.info(“详细输出”)
其他:
log.basicConfig(格式=“%(levelname)s:%(消息)s”)
log.info(“这应该是详细的。”)
log.warning(“这是一个警告”)
log.error(“这是一个错误”)
所有这些都会自动转到stderr
:
%python myprogram.py
警告:这是一个警告。
错误:这是一个错误。
%python myprogram.py-v
信息:详细输出。
信息:这应该是冗长的。
警告:这是一个警告。
错误:这是一个错误。
有关更多信息,请参阅和。我为我的一个项目偷了。查看
virtualenv.py
的main()
,查看代码中是否散布了logger.notify()
,logger.info()
,logger.warn()
,等等。实际发出输出的方法取决于virtualenv是否是使用-v
、-vv
、-vvv
、或-q
调用的。我需要的是一个打印对象(obj)的函数,但只有当全局变量verbose为true时,否则它不会执行任何操作
我希望能够随时更改全局参数“verbose”。简单性和可读性对我来说至关重要。因此,我将按照以下几行指示进行:
ak@HP2000:~$ python3
Python 3.4.3 (default, Oct 14 2015, 20:28:29)
[GCC 4.8.4] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> verbose = True
>>> def vprint(obj):
... if verbose:
... print(obj)
... return
...
>>> vprint('Norm and I')
Norm and I
>>> verbose = False
>>> vprint('I and Norm')
>>>
全局变量“verbose”也可以从参数列表中设置。不适用于我的Python版本3.5@styles在他的评论中正确地指出原因是附加的可选关键字参数。因此,我对Python 3稍微改进的版本如下所示:
if verbose:
def verboseprint(*args):
# Print each argument separately so caller doesn't need to
# stuff everything to be printed into a single string
for arg in args:
print arg,
print
else:
verboseprint = lambda *a: None # do-nothing function
% python verbose-tester.py -v
ERROR message
% python verbose=tester.py -vv
WARN message
ERROR message
% python verbose-tester.py -vvv
INFO message
WARN message
ERROR message
if VERBOSE:
def verboseprint(*args, **kwargs):
print(*args, **kwargs)
else:
verboseprint = lambda *a, **k: None # do-nothing function
可能有一个全局变量,可能是由
sys.argv
中的argparse
设置的,表示程序是否应该详细。
然后,可以编写一个decorator,这样,如果启用了verbosity,那么只要函数运行,标准输入就会转移到null设备中:
import os
from contextlib import redirect_stdout
verbose = False
def louder(f):
def loud_f(*args, **kwargs):
if not verbose:
with open(os.devnull, 'w') as void:
with redirect_stdout(void):
return f(*args, **kwargs)
return f(*args, **kwargs)
return loud_f
@louder
def foo(s):
print(s*3)
foo("bar")
这个答案的灵感来自于;实际上,我打算在我的程序中将它作为一个模块使用,但我遇到了一些我无法理解的错误,所以我修改了它的一部分
此解决方案的缺点是,冗余是二进制的,这与日志记录不同,后者允许对程序的冗余程度进行更精细的调整。
另外,所有打印
调用都被转移,这可能是不需要的。为什么不使用日志模块,默认设置日志级别信息,并在传递--verbose时进行调试?最好不要重新实现该语言中已有的任何东西…@Tim,我同意,但是日志模块非常痛苦。更好的是,使用print
函数:接受许多参数。它可以在3.x中实现为print(*args)
,在2.x中实现为args中arg的:print arg、
。主要的优点是,它允许在一条消息中混合字符串和其他类型的内容,而无需显式的str
调用/格式化和连接。在print arg,
行末尾使用的逗号是什么?这很容易由个人自行实验或通过检查