如何在脚本中实现–verbose或-v选项?
我知道--verbose
或-v
从几个工具,我想实现这个到我自己的一些脚本和工具。
我想到了放置
if verbose: print ...
通过我的源代码,以便如果用户通过-v
选项,variablesverbose
将被设置为True
,文本将被打印。
这是正确的方法还是有更常见的方法?
另外:我不是要求一个方法来实现参数的parsing。 我知道它是如何完成的。 我只对verbose选项特别感兴趣。 谢谢!
我的build议是使用一个function。 但是,不要把这个if
放在你可能想要做的function上,而是这样做:
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
(是的,你可以在if
语句中定义一个函数,只有当条件为真时才会被定义)。
如果您使用的是Python 3,其中print
已经是一个函数(或者如果您愿意在2.x中使用print
作为函数,使用from __future__ import print_function
), from __future__ import print_function
简单:
verboseprint = print if verbose else lambda *a, **k: None
这样,如果详细模式closures(使用lambda),函数被定义为无所事事,而不是经常testingverbose
标志。
如果用户在程序运行期间可以更改详细模式,这将是一个错误的方法(你需要if
在函数中),但是因为你用一个命令行标志来设置它,所以你只需要做一次决定。
然后,您可以使用例如verboseprint("look at all my verbosity!", object(), 3)
每当您想打印一个“详细”的消息。
使用logging
模块:
import logging as log … args = p.parse_args() if args.verbose: log.basicConfig(format="%(levelname)s: %(message)s", level=log.DEBUG) log.info("Verbose output.") else: log.basicConfig(format="%(levelname)s: %(message)s") log.info("This should be verbose.") log.warning("This is a warning.") log.error("This is an error.")
所有这些都会自动转到stderr
:
% python myprogram.py WARNING: This is a warning. ERROR: This is an error. % python myprogram.py -v INFO: Verbose output. INFO: This should be verbose. WARNING: This is a warning. ERROR: This is an error.
有关更多信息,请参阅Python文档和教程 。
我在脚本中做的是在运行时检查是否设置了“verbose”选项,然后将日志级别设置为debug。 如果没有设置,我把它设置为信息。 这样你就没有“如果详细”检查你的代码。
build立和简化@ kindall的答案,这是我通常使用的:
v_print = None def main() parser = argparse.ArgumentParser() parser.add_argument('-v', '--verbosity', action="count", help="increase output verbosity (eg, -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")
你的脚本可以这样调用:
% 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
一对夫妇笔记:
- 你的第一个参数是你的错误级别,第二个是你的消息。 它有
3
神奇的数字,为你的日志logging设置了上限,但是我接受这个作为简单的妥协。 - 如果你想
v_print
在你的程序中工作,你必须做的全球垃圾。 这没有什么乐趣,但我挑战有人find更好的方法。
如果你有一个叫vprint
的函数,它可能会更干净,它会为你检查详细的标志。 那么你只需要调用你自己的vprint
函数就可以了。
我偷了 virtualenv 的日志代码为我的一个项目。 在virtualenv.py
main()
中查看它是如何初始化的。 代码被logger.notify()
, logger.info()
, logger.warn()
等等。 哪些方法实际发出的输出取决于是否使用-v
, -vv
, -vvv
或-q
调用virtualenv。
我需要的是一个打印一个对象(obj)的函数,但只有在全局variablesverbose为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') >>>
全局variables“verbose”也可以从参数列表中设置。
@ kindall的解决scheme不适用于我的Python版本3.5。 @styles在他的评论中正确地指出,原因是附加的可选关键字参数。 因此,我为Python 3稍微改进的版本如下所示:
if VERBOSE: def verboseprint(*args, **kwargs): print(*args, **kwargs) else: verboseprint = lambda *a, **k: None # do-nothing function