2010-11-03 7 views
6

Tengo un montón de llamadas print que necesito escribir en un archivo en lugar de stdout. (No necesito stdout en absoluto.)imprimiendo a un archivo en Python: redirigir contra el argumento de archivo de impresión frente a escribir

Estoy considerando tres enfoques. ¿Hay alguna ventaja (incluido el rendimiento) en cualquiera de ellos?

redirección completa, que vi here:

import sys 

saveout = sys.stdout 
fsock = open('out.log', 'w') 
sys.stdout = fsock 

print(x) 
# and many more print calls 

# later if I ever need it: 
# sys.stdout = saveout 
# fsock.close() 

redirección en cada sentencia print:

fsock = open('out.log', 'w') 
print(x, file = fsock) 
# and many more print calls 

función de escritura:

fsock = open('out.log', 'w') 
fsock.write(str(x)) 
# and many more write calls 
+0

si está utilizando py3k read [diveintopython 3] (http://diveintopython3.org/) – SilentGhost

+0

olvidé agregar que hice una pregunta relacionada hace poco tiempo. http://stackoverflow.com/questions/4090652/where-to-store-a-log-file-name-in-python – max

+0

En caso de duda, perfil. http://docs.python.org/py3k/library/profile.html –

Respuesta

6

No esperaría ninguna diferencia de rendimiento duradera entre estos enfoques.

La ventaja del primer enfoque es que cualquier código razonablemente bueno en el que confíe (los módulos que importa) recogerá automáticamente su redirección deseada.

El segundo enfoque no tiene ninguna ventaja. Solo es adecuado para la depuración o el código descartable ... y ni siquiera es una buena idea para eso. Desea que sus decisiones de salida se consoliden en unos pocos lugares bien definidos, no dispersos por su código en cada llamada al print(). En Python3 print() es una función en lugar de una declaración. Esto le permite volver a definirlo, si lo desea. Entonces puede def print(*args) si lo desea. También puede llamar al __builtins__.print() si necesita acceder a él, dentro de la definición de su propio print() personalizado, por ejemplo.

El tercer enfoque ... y por extensión, el principio de que toda su salida debe generarse en funciones específicas y métodos de clase que defina para ese fin ... es probablemente el mejor.

Debe mantener la salida y el formato separados de su funcionalidad principal tanto como sea posible. Al mantenerlos separados, permite que su núcleo sea reutilizado. (Por ejemplo, puede comenzar con algo que está destinado a ejecutarse desde una consola de texto/shell, y luego debe proporcionar una interfaz de usuario web, una interfaz de usuario de pantalla completa (curses) o una GUI para ello. También puede crear una funcionalidad completamente diferente alrededor ...en situaciones en las que los datos resultantes deben devolverse en su forma nativa (como objetos) en lugar de extraerlos como texto (salida) y volver a analizarlos en objetos nuevos.

Por ejemplo, he tenido más de una ocasión en la que escribí algo para realizar consultas complejas y recopilar datos de varias fuentes e imprimir un informe ... decir las discrepancias ... más adelante deben adaptarse a un formulario que podría escupir los datos de alguna forma (como YAML/JSON) que podrían alimentar a otro sistema (por ejemplo, para reconciliar una fuente de datos con otra.

Si, desde el principio, mantiene la fuente principal operaciones separadas de la salida y formateo, entonces este tipo de adaptación es relativamente fácil. De lo contrario, implica un poco de refactorización (a veces equivalente a una reescritura completa).

4

A partir de los nombres de archivo que está utilizando en su pregunta, parece que quiere crear un archivo de registro. ¿Has considerado el módulo Python logging?

+0

vea la historia reciente de OP – SilentGhost

+0

Al final decidí no usar 'logging'. Tengo varios archivos para escribir y me resultó más fácil de administrar por mi cuenta. Pero gracias, lo tendré en cuenta. – max

4

creo que la semántica es imporante:

Yo sugeriría primera aproximación para la situación en la que la impresión de la misma materia que imprimiría consola. La semántica será la misma. Para una situación más compleja, usaría el módulo de registro estándar.

El segundo y tercer enfoque son un poco diferentes en caso de que esté imprimiendo líneas de texto. Segunda aproximación - print agrega la nueva línea y write no.

Usaría el tercer acercamiento en formato de escritura principalmente binario o no textual y usaría el redireccionamiento en la declaración de impresión en la mayoría de los otros casos.

+1

+1: información de nueva línea. – max

Cuestiones relacionadas