How to implement the --verbose or -v option into a script?

后端 未结 9 1127
渐次进展
渐次进展 2020-12-12 10:35

I know the --verbose or -v from several tools and I\'d like to implement this into some of my own scripts and tools.

I thought of placing:<

相关标签:
9条回答
  • 2020-12-12 10:49

    I stole the logging code from virtualenv for a project of mine. Look in main() of virtualenv.py to see how it's initialized. The code is sprinkled with logger.notify(), logger.info(), logger.warn(), and the like. Which methods actually emit output is determined by whether virtualenv was invoked with -v, -vv, -vvv, or -q.

    0 讨论(0)
  • 2020-12-12 10:56

    What I need is a function which prints an object (obj), but only if global variable verbose is true, else it does nothing.

    I want to be able to change the global parameter "verbose" at any time. Simplicity and readability to me are of paramount importance. So I would proceed as the following lines indicate:

    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')
    >>> 
    

    Global variable "verbose" can be set from the parameter list, too.

    0 讨论(0)
  • 2020-12-12 10:57

    What I do in my scripts is check at runtime if the 'verbose' option is set, and then set my logging level to debug. If it's not set, I set it to info. This way you don't have 'if verbose' checks all over your code.

    0 讨论(0)
  • 2020-12-12 11:04

    My suggestion is to use a function. But rather than putting the if in the function, which you might be tempted to do, do it like this:

    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
    

    (Yes, you can define a function in an if statement, and it'll only get defined if the condition is true!)

    If you're using Python 3, where print is already a function (or if you're willing to use print as a function in 2.x using from __future__ import print_function) it's even simpler:

    verboseprint = print if verbose else lambda *a, **k: None
    

    This way, the function is defined as a do-nothing if verbose mode is off (using a lambda), instead of constantly testing the verbose flag.

    If the user could change the verbosity mode during the run of your program, this would be the wrong approach (you'd need the if in the function), but since you're setting it with a command-line flag, you only need to make the decision once.

    You then use e.g. verboseprint("look at all my verbosity!", object(), 3) whenever you want to print a "verbose" message.

    0 讨论(0)
  • 2020-12-12 11:04

    There could be a global variable, likely set with argparse from sys.argv, that stands for whether the program should be verbose or not. Then a decorator could be written such that if verbosity was on, then the standard input would be diverted into the null device as long as the function were to run:

    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")
    

    This answer is inspired by this code; actually, I was going to just use it as a module in my program, but I got errors I couldn't understand, so I adapted a portion of it.

    The downside of this solution is that verbosity is binary, unlike with logging, which allows for finer-tuning of how verbose the program can be. Also, all print calls are diverted, which might be unwanted for.

    0 讨论(0)
  • 2020-12-12 11:06

    @kindall's solution does not work with my Python version 3.5. @styles correctly states in his comment that the reason is the additional optional keywords argument. Hence my slightly refined version for Python 3 looks like this:

    if VERBOSE:
        def verboseprint(*args, **kwargs):
            print(*args, **kwargs)
    else:
        verboseprint = lambda *a, **k: None # do-nothing function
    
    0 讨论(0)
提交回复
热议问题