如何在脚本中实现--verbose或-v选项?

Auf*_*ind 78 python option

我知道--verbose或者-v来自几个工具,我想将它实现到我自己的一些脚本和工具中.

我想放置:

if verbose:
    print ...
Run Code Online (Sandbox Code Playgroud)

通过我的源代码,这样如果用户传递-v选项,变量verbose将被设置为True,文本将被打印.

这是正确的方法还是有更常见的方法?

另外:我不是要求一种方法来实现参数的解析.我知道它是如何完成的.我只对verbose选项感兴趣.

kin*_*all 93

我的建议是使用一个函数.但是,不要把它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
Run Code Online (Sandbox Code Playgroud)

(是的,您可以在if语句中定义一个函数,只有在条件为真时才会定义它!)

如果您正在使用Python 3,那么print它已经是一个函数(或者如果您愿意print在2.x中使用from __future__ import print_function它作为函数),它甚至更简单:

verboseprint = print if verbose else lambda *a, **k: None
Run Code Online (Sandbox Code Playgroud)

这样,如果详细模式关闭(使用lambda),则该函数被定义为无操作,而不是不断地测试verbose标志.

如果用户可以程序运行期间更改详细程度模式,这将是错误的方法(您需要if在函数中),但由于您使用命令行标志设置它,您只需要做出一次决定.

然后,verboseprint("look at all my verbosity!", object(), 3)只要您想打印"详细"消息,就可以使用eg .

  • Python 3打印函数也采用可选的关键字参数,因此要完全重现print的功能:`def verboseprint(*args,**kwargs):print(*args,**kwargs)` (4认同)

Pro*_*sch 55

使用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.")
Run Code Online (Sandbox Code Playgroud)

所有这些都自动转到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.
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅Python文档教程.

  • 根据Python Docs [here](https://docs.python.org/2/howto/logging.html#logging-basic-tutorial),在您只需要打印输出的情况下不应使用日志记录.正常执行程序.看起来这就是OP想要的. (7认同)
  • 这对于基本问题来说似乎很好,但许多 *nix 命令还支持多个级别的详细程度(-v -v -v 等),这样可能会变得混乱。 (2认同)

mli*_*ner 11

建立和简化@ 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()
Run Code Online (Sandbox Code Playgroud)

然后,在整个脚本中提供以下用法:

v_print(1, "INFO message")
v_print(2, "WARN message")
v_print(3, "ERROR message")
Run Code Online (Sandbox Code Playgroud)

你的脚本可以这样调用:

% 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
Run Code Online (Sandbox Code Playgroud)

几个笔记:

  1. 你的第一个参数是你的错误级别,第二个参数是你的错误.它有神奇的数字3设置你的日志记录的上限,但我接受这是为了简单的妥协.
  2. 如果你想v_print在整个程序中工作,你必须使用全局的垃圾.这没什么好玩的,但我挑战某人找到更好的方法.

  • 是的,这是一个公平的观点。日志记录有一些我试图避免的认知开销,但这可能是“正确”的做法。过去只是让我很恼火...... (2认同)

jon*_*esy 9

我在脚本中执行的操作是在运行时检查是否设置了'verbose'选项,然后将我的日志记录级别设置为debug.如果没有设置,我将其设置为info.这样,您就不会在代码中进行"if verbose"检查.


Geo*_*lly 5

我从virtualenv中窃取了我的一个项目的日志代码。查看 来看看它是如何初始化的。代码中散布着、、等。哪些方法实际发出输出取决于 virtualenv 是否使用、、或 调用。main()virtualenv.pylogger.notify()logger.info()logger.warn()-v-vv-vvv-q