Pregunta ¿Cuál es una manera fácil de implementar una opción --quiet en una secuencia de comandos python


Estoy trabajando en un script de python de línea de comando. A lo largo del script, tengo mucha información. print-hacia la ventana de la terminal para poder seguir lo que está sucediendo.

Utilizando OptionParser Quiero agregar un --quiet opción para que pueda silenciar toda la salida. Estoy buscando una forma pitónica de implementar esto a lo largo del script para que yo no lo hagas terminar haciendo algo como:

if not QUIET: # global variable set by OptionParser
    print " my output "

Soy nuevo en Python y estoy seguro de que hay una mejor manera. Ideas?


14
2017-11-29 15:08


origen


Respuestas:


Podrías usar logging y asignar aquellas cosas que no deberían imprimirse si QUIET un nivel de registro diferente.

Editar:  La respuesta de THC4K muestra un ejemplo de cómo hacerlo, suponiendo que todos los resultados deberían ser silenciosos si QUIET Está establecido. Tenga en cuenta que en Python 3 from __future__ import print_function no es necesario:

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

Para un resultado importante que no debe ser silenciado por --quiet, defina, por ejemplo, iprint:

iprint = logging.warning

27
2017-11-29 15:13



puede silenciar todas la salida ejecutándola como python myscript.py > /dev/null

cambiar las secuencias de salida en el script:

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

usar una función de impresión diferente

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

use logging y 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 )

11
2017-11-29 15:27



¿Por qué no modificas tu función de salida en función de si el programa está en modo silencioso, por lo que solo haces el control una vez?

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

O bien, podrías poner el cheque por QUIET dentro de tu función de salida:

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

La situación que ha descrito es en realidad una de las razones por las que Python 3 ha cambiado print de una palabra clave a una función real: los proyectos grandes de las personas se estaban volviendo muy dependientes de print siendo una palabra clave, y luego cuando llegó el momento de modificar cómo se grabó la producción, se requirió una refactorización masiva; mientras que cuando print es una función adecuada, puedes redefinirla, para que print(foo) saldría a un archivo de registro, por ejemplo. Es por eso que es mejor práctica envolver su salida / registro en una función real, en lugar de tener print dispersos sobre tu script


2
2017-11-29 15:10



Puede reemplazar stdout con un proxy que filtra las llamadas a escribir o 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)

La ventaja de esto es que es multiplataforma (a diferencia de escribir en / dev / null) y seguirá funcionando para las instrucciones de impresión en bibliotecas de terceros sobre las que no tiene control. También podría refinarlo aún más para tener más control sobre lo que está escrito, p. Ej. para agregar una marca de tiempo o redirigir las instrucciones de impresión al sistema de registro.


1
2017-11-29 16:21



Si lo quieres rápido y sucio y quieres deshacerte de él todas salida luego redireccione stdout y stderr a / dev / null. Poner:

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

En el punto donde detectas --quiet.


0
2017-11-29 15:12



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

En Windows, use "nul" en lugar de "/ dev / null"


0
2017-11-29 15:15