开发者

What's an easy way to implement a --quiet option in a python script

Am working on a command line python script - throughout the script, I have a lot of information I am print-ing to the terminal window so that I may follow along with what is happening.

Using OptionParser I want to add a --quiet option so I can silence all the output. I am looking for a pythonic way to go about implementing this throughout the script so that I don't end up doing something like:

if not QUIET: # global variable set by OptionParser
    print " my output 开发者_如何学编程"

Am new to python and sure there is a better way. Ideas?


You could use logging and assign those things that should not be printed if QUIET a different log level.

Edit: THC4K's answer shows an example of how to do this, assuming that all output should be silent if QUIET is set. Note that in Python 3 from __future__ import print_function is not necessary:

print = logging.info
logging.basicConfig(level=logging.WARNING if QUIET else logging.INFO,
                    format="%(message)s")

For for important output that should not be silenced by --quiet, define e.g. iprint:

iprint = logging.warning


can silence all the output by running it as python myscript.py > /dev/null

change the output streams in the script:

if QUIET:
    sys.stdout = open(os.devnull, 'a')
    sys.stderr = open(os.devnull, 'a')
print(something)

use a different print function

from __future__ import print_function
if QUIET:
    def print(*args):
        pass
print(something)

use logging and loglevels

from __future__ import print_function
import logging
logging.basicConfig(level=logging.INFO, format="%(message)s")
print = logging.info
if QUIET:
    logging.basicConfig(level=logging.ERROR)

print(something)


Why don't you just modify your output function based on whether the program is in quiet mode, so you only do the check once?

if QUIET:
    def DoOutput(stuff):
        pass
else:
    def DoOutput(stuff):
        print(stuff)

Or, you could of course put the check for QUIET inside your output function:

def DoOutput(stuff):
    if QUIET:
        print(stuff)

The situation that you've described is actually one of the reasons that Python 3 has changed print from a keyword to an actual function: people's large projects were becoming very dependent on print being a keyword, and then when it came time to modify how output was recorded, it required a massive refactoring; whereas when print is a proper function, you can just redefine it, so that print(foo) would output to a log file, for instance. That's why it's better practice to wrap your output/logging in an actual function, rather than having print scattered about your script.


You could replace stdout with a proxy that filters calls to write or writelines:

class FileProxy(object):
    def __init__(self, real_file, quiet_flag):
        self.real_file = real_file
        self.quiet_flag = quiet_flag

    def write(self, string):
        if not self.quiet_flag:
            self.real_file.write(string)

    def writelines(self, strings):
        if not self.quiet_flag:
            self.real_file.write(strings)

    def __getattr__(self, name):
        return getattr(self.file, name)

import sys
sys.stdout = FileProxy(sys.stdout, QUIET)

The advantage of this is that it is cross platform (unlike writing to /dev/null) and it will still work for print statements in third-party libraries that you do not have control over. You could also refine it further to give more control over exactly what is written, e.g. to add a timestamp, or redirect print statements to the logging system.


If you want it quick and dirty and you want to get rid of all output then redirect stdout and stderr to /dev/null. Put:

sys.stdout = open("/dev/null", "a")
sys.stderr = open("/dev/null", "a")

At the point where you detect --quiet.


if QUIET:
   sys.stdout=open("/dev/null","w")
...
print 'my output'

On Windows, use "nul" instead of "/dev/null"

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜