如何在脚本中实现–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 

一对夫妇笔记:

  1. 你的第一个参数是你的错误级别,第二个是你的消息。 它有3神奇的数字,为你的日志logging设置了上限,但是我接受这个作为简单的妥协。
  2. 如果你想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