| You are here: Inicio > Inmersión en Python > Scripts y flujos > Entrada, salida y error estándar | << >> | ||||
Inmersión en PythonPython de novato a experto |
|||||
Los usuarios de UNIX ya estarán familiarizados con el concepto de entrada estándar, salida estándar y salida estándar de error. Esta sección es para los demás.
La salida estándar y la salida estándar de error (se suelen abreviar stdout y stderr) son tuberías[13] incorporadas en todo sistema UNIX. Cuando se imprime algo, sale por la tubería stdout; cuando el programa aborta e imprime información de depuración (como el traceback de Python), sale por la tubería stderr. Ambas se suelen conectar a la ventana terminal donde está trabajando usted para que cuando el programa imprima, usted vea la salida, y cuando un programa aborte, pueda ver la información de depuración. (Si está trabajando en un sistema con un IDE de Python basado en ventanas, stdout y stderr descargan por omisión en la “Ventana interactiva”).
>>> for i in range(3): ... print 'Dive in'Dive in Dive in Dive in >>> import sys >>> for i in range(3): ... sys.stdout.write('Dive in')
Dive inDive inDive in >>> for i in range(3): ... sys.stderr.write('Dive in')
Dive inDive inDive in
| Como pudo ver en Ejemplo 6.9, “Contadores simples”, se puede utilizar la función incorporada range de Python para construir bucles contadores simples que repitan algo un número determinado de veces. | |
| stdout es un objeto de tipo fichero; llamar a su función write imprimirá la cadena que se le pase. De hecho, esto es lo que hace realmente la función print; añade un retorno de carro al final de la cadena que esté imprimiendo e invoca a sys.stdout.write. | |
| En el caso más simple stdout y stderr envían su salida al mismo lugar: al IDE de Python (si está en uno), o a la terminal (si ejecuta Python desde la línea de órdenes). Igual que stdout, stderr no añade un retorno de carro por sí sola; si lo desea, añádalo usted mismo. |
stdout y stderr son ambos objetos de tipo fichero, como aquellos de los que hablamos en Sección 10.1, “Abstracción de fuentes de datos”, pero ambos son sólo de escritura. No tienen método read, sólo write. Aún así son objetos de tipo fichero, y puede asignarles cualquier otro objeto de tipo fichero para redirigir su salida.
[usted@localhost kgp]$ python stdout.py Dive in [usted@localhost kgp]$ cat out.log This message will be logged instead of displayed
(On Windows, you can use type instead of cat to display the contents of a file.)
Si aún no lo ha hecho, puede descargar éste ejemplo y otros usados en este libro.
#stdout.py import sys print 'Dive in'saveout = sys.stdout
fsock = open('out.log', 'w')
sys.stdout = fsock
print 'This message will be logged instead of displayed'
sys.stdout = saveout
fsock.close()
![]()
La redirección de stderr funciona exactamente igual, usando sys.stderr en lugar de sys.stdout.
[usted@localhost kgp]$ python stderr.py [usted@localhost kgp]$ cat error.log Traceback (most recent line last): File "stderr.py", line 5, in ? raise Exception, 'this error will be logged' Exception: this error will be logged
Si aún no lo ha hecho, puede descargar éste ejemplo y otros usados en este libro.
#stderr.py import sys fsock = open('error.log', 'w')sys.stderr = fsock
raise Exception, 'this error will be logged'
![]()
![]()
Dado que es tan común escribir los mensajes de error a la salida de errores, hay una sintaxis abreviada que puede usar en lugar de tomarse las molestias de hacer la redirección explícita.
>>> print 'entering function' entering function >>> import sys >>> print >> sys.stderr, 'entering function'entering function
La entrada estándar, por otro lado, es un objeto de fichero de sólo lectura, y representa los datos que fluyen dentro del programa desde alguno previo. Esto no tendrá mucho sentido para los usuarios del Mac OS clásico, o incluso de Windows que no se manejen de forma fluida en la línea de órdenes de MS-DOS. La manera en que trabaja es que se pueden construir cadenas de órdenes en una única línea, de manera que la salida de un programa se convierte en la entrada del siguiente en la cadena. El primer programa se limita a imprimir en la salida estándar (sin hacer ningún tipo de redirección explícita, sólo ejecuta sentencias print normales, o lo que sea), y el siguiente programa lee de la entrada estándar, y es el sistema operativo el que se encarga de conectar la salida de un programa con la entrada del siguiente.
[usted@localhost kgp]$ python kgp.py -g binary.xml01100111 [usted@localhost kgp]$ cat binary.xml
<?xml version="1.0"?> <!DOCTYPE grammar PUBLIC "-//diveintopython.org//DTD Kant Generator Pro v1.0//EN" "kgp.dtd"> <grammar> <ref id="bit"> <p>0</p> <p>1</p> </ref> <ref id="byte"> <p><xref id="bit"/><xref id="bit"/><xref id="bit"/><xref id="bit"/>\ <xref id="bit"/><xref id="bit"/><xref id="bit"/><xref id="bit"/></p> </ref> </grammar> [usted@localhost kgp]$ cat binary.xml | python kgp.py -g -
![]()
10110001
| Como vio en Sección 9.1, “Inmersión”, esto imprimirá una cadena de ocho bits al azar, 0 o 1. | |
| Esto imprime simplemente el contenido entero de binary.xml. (Los usuarios de Windows deberían usar type en lugar de cat). | |
| Esto imprime el contenido de binary.xml, pero el carácter “|”, denominado carácter de “tubería”, implica que el contenido no se imprimirá en la pantalla. En su lugar se convertirá en la entrada estándar de la siguiente orden, que en este caso llama al script de Python. | |
| En lugar de especificar un módulo (como binary.xml), especificamos “-”, que hace que el script carge la gramática desde la entrada estándar en lugar de un fichero específico en el disco (más sobre esto en el siguiente ejemplo). Así que el efecto es el mismo que en la primera sintaxis, donde especificábamos directamente el nombre de fichero de la gramática, pero piense el aumento de posibilidades aquí. En lugar de hacer simplemente cat binary.xml, podría ejecutar un script que genere la gramática de forma dinámica, y entonces pasarlo a otro script mediante una tubería. Puede venir de cualquier parte: una base de datos o algún tipo de meta-script generador de gramáticas, o lo que sea. La idea es que no hace falta cambiar el script kgp.py para incorporar esta funcionalidad. Todo lo que necesita es la capacidad de obtener todos los ficheros de gramática por la entrada estándar, y así podrá desplazar toda la lógica a otro programa. |
Entonces, ¿cómo “sabe” el script que ha de leer de la entrada estándar cuando el fichero de la gramática es “-”? No es magia; es código.
def openAnything(source): if source == "-":import sys return sys.stdin # try to open with urllib (if source is http, ftp, or file URL) import urllib try: [... corte ...]
| Ésta es la función openAnything de toolbox.py, que examinamos antes en Sección 10.1, “Abstracción de fuentes de datos”. Todo lo que hemos hecho es añadir tres líneas de código al principio de la función para comprobar si la fuente es “-”; y en ese caso devolvemos sys.stdin. ¡Sí, eso es todo! Recuerde, stdin es un objeto de tipo fichero con método read, así que el resto del código (en kgp.py, donde llama a openAnything) no cambia un ápice. |
[13]
<< Scripts y flujos |
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
Caché de búsqueda de nodos >> |