Hay varios modos de presentar la salida de un programa; se pueden imprimir datos en un modo legible a los humanos o escribirlos en un fichero para uso posterior. Este cap�tulo explora algunas de las posibilidades.
Hasta ahora hemos encontrado dos modos de escribir valores: las sentencias
de expresi�n y la sentencia print Hay un tercer modo, utilizar
el m�todo write() de los objetos fichero, donde se puede
acceder al fichero
de salida est�ndar es accesible mediante sys.stdout
. Consulta
la Referencia de las bibliotecas si deseas obtener informaci�n sobre el tema.
A menudo, querr�s tener m�s control sobre el formato de la salida que
escribir valores separados por espacios. Hay dos modos de dar formato a la salida:
El primer modo es gestionar t� mismo las cadenas. Mediante corte y empalme
de cadenas se puede generar cualquier formato. El m�dulo est�ndar
string contiene operaciones �tiles para
ajustar cadenas a un ancho de columna dado. Esto se discutir� en breve.
El segundo modo es utilizar el operador %
con una cadena como
argumento izquierdo. El operador %
interpreta el argumento izquierdo como una cadena
de formato estilo sprintf() de C, que ha de ser aplicado sobre el
argumento derecho para devolver la cadena resultante del formato.
Queda una cuesti�n, por supuesto: �C�mo convertir valores a cadenas?
Afortunadamente, Python tiene un modo de convertir cualquier valor a cadena:
pasarle la funci�n repr() o, simplemente, escribir el valor entre
comillas simples invertidas (``
). He aqu� algunos ejemplos:
>>> x = 10 * 3.14 >>> y = 200*200 >>> s = 'El valor de "x" es ' + `x` + ' e "y" vale ' + `y` + '...' >>> print s El valor de "x" es 31.4 e "y" vale 40000... >>> # Las comillas invertidas funcionan sobre otros tipos, adem�s de los n�meros: ... p = [x, y] >>> ps = repr(p) >>> ps '[31.4, 40000]' >>> # Convertir a cadena a�ade a las cadenas comillas y barras invertidas: ... hola = 'hola, mundo\n' >>> cadhola = `hola` >>> print cadhola 'hola, mundo\012' >>> # El argumento de las comillas invertidas puede ser una tupla: ... `x, y, ('fiambre', 'huevos')` "(31.4, 40000, ('fiambre', 'huevos'))"
He aqu� dos modos de escribir una tabla de cuadrados y cubos:
>>> import string >>> for x in range(1, 11): ... print string.rjust(`x`, 2), string.rjust(`x*x`, 3), ... # Observa la coma final de la l�nea anterior ... print string.rjust(`x*x*x`, 4) ... 1 1 1 2 4 8 3 9 27 4 16 64 5 25 125 6 36 216 7 49 343 8 64 512 9 81 729 10 100 1000 >>> for x in range(1,11): ... print '%2d %3d %4d' % (x, x*x, x*x*x) ... 1 1 1 2 4 8 3 9 27 4 16 64 5 25 125 6 36 216 7 49 343 8 64 512 9 81 729 10 100 1000
Observa que se ha a�adido un espacio entre columnas por el modo en que funciona print: siempre a�ade un espacio entre sus argumentos.
Este ejemplo utiliza la funci�n string.rjust(), que ajusta a la derecha una cadena dada una anchura determinada, a�adiendo espacios a la izquierda. Existen las funciones relacionadas string.ljust() y string.center(). Estas funciones no escriben nada, s�lo devuelven una cadena nueva. Si la cadena de entrada es demasiado larga, no la recortan, sino que la devuelven sin cambios. Se embrollar� la salida, pero suele ser mejor que falsear los valores (si es preferible truncar la salida, siempre se puede agregar una operaci�n de corte, como "string.ljust(x,n)[0:n]").
Existe otra funci�n, string.zfill(), que rellena una cadena num�rica por la izquierda con ceros. Entiende de signos positivo y negativo:
>>> import string >>> string.zfill('12', 5) '00012' >>> string.zfill('-3.14', 7) '-003.14' >>> string.zfill('3.14159265359', 5) '3.14159265359'
%
tiene este aspecto:
>>> import math >>> print 'El valor de PI es aproximadamente %5.3f.' % math.pi El valor de PI es aproximadamente 3.142.
Si hay m�s de un formato en la cadena, se ha de pasar una tupla como operando derecho, como aqu�:
>>> tabla = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 7678} >>> for nombre, telef in tabla.items(): ... print '%-10s ==> %10d' % (nombre, telef) ... Jack ==> 4098 Dcab ==> 7678 Sjoerd ==> 4127
La mayor�a de los formatos funcionan como en C y exigen que se pase el
tipo correcto. Sin embargo, de no hacerlo as�, s�lo se causa una excepci�n
y no un volcado de memoria (o error de protecci�n general).
El formato %s
es m�s relajado: Si el argumento correspondiente
no es un objeto de cadena, se convierte a cadena mediante la funci�n interna
str(). Es posible pasar *
para indicar la precisi�n o
anchura como argumento (entero) aparte. No se puede utilizar los formatos de C
%n
ni %p
.
Si tienes una cadena de formato realmente larga que no deseas dividir,
ser�a un detalle hacer referencia a las variables por su nombre, en vez de
por su posici�n. Esto se logra con una extensi�n a los formatos de C,
con el formato %(nombre)formato
, por ejemplo:
>>> tabla = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678} >>> print 'Jack: %(Jack)d; Sjoerd: %(Sjoerd)d; Dcab: %(Dcab)d' % tabla Jack: 4098; Sjoerd: 4127; Dcab: 8637678
Esto resulta particularmente pr�ctico en combinaci�n con la nueva funci�n interna vars(), que devuelve un diccionario que contiene todas las variables locales.
open() (abrir) devuelve un objeto fichero. Se suele usar con dos argumentos: "open(nombreFichero, modo)".
>>> f=open('/tmp/fichTrabajo', 'w') >>> print f <open file '/tmp/fichTrabajo', mode 'w' at 80a0960>
El primer argumento es una cadena que contiene el nombre del fichero.
El segundo argumento es otra cadena que contiene caracteres que describen
el modo en que se va a utilizar el fichero. El modo puede ser 'r'
,
cuando s�lo se va a leer del fichero, 'w'
, si s�lo se va a escribir
(y si existe un fichero del mismo nombre se borra) o 'a'
, que
abre el fichero para a�adir datos. En el modo 'a'
, cualquier dato que
se escriba en el fichero
se a�adir� al final de los datos existentes. El argumento de modo es
opcional. Se supone 'r'
si se omite.
En Windows y Macintosh, al a�adir 'b'
al modo, el fichero se abre
en modo binario, por lo que existen modos como 'rb'
, 'wb'
y 'r+b'
.
Windows distingue entre ficheros de texto y binarios: los caracteres de
fin de l�nea de los ficheros de texto se alteran ligeramente de forma autom�tica
al leer o escribir datos. Esta modificaci�n oculta no afecta en el caso
de ficheros de texto ASCII, pero corrompe los ficheros de datos binarios,
tales como ficheros JPEG o .EXE. Ten mucho cuidado de utilizar el modo
binario al leer y escribir dichos ficheros (observa que el comportamiento
preciso del modo de texto en Macintosh depende de la biblioteca C subyacente).
El resto de los ejemplos de esta secci�n supondr�n que se ha
creado previamente un objeto fichero denominado f
.
Para leer el contenido de un fichero, llama a
f.read(cantidad)
,
que lee cierta cantidad de datos y los devuelve como cadena.
cantidad
es un argumento num�rico opcional. Si se omite o es negativo, se leer�
y devolver� el contenido completo del fichero. Es problema tuyo si
el fichero tiene un tama�o descomunal. Si se incluye el argumento y es
positivo, se leen y devuelven como m�ximo cantidad bytes.
Si se hab�a alcanzado el final de fichero, f.read()
s�lo
devuelve una cadena vac�a (""
).
>>> f.read() 'Esto es el fichero completo.\012' >>> f.read() ''
f.readline()
lee una sola l�nea del fichero. Se deja un car�cter
de cambio de l�nea (\n
) al final de la cadena, que se omite s�lo en
la �ltima l�nea, siempre que el fichero no termine en un salto de l�nea.
De este modo se consigue que el valor devuelto no sea ambiguo. Si
f.readline()
devuelve
una cadena vac�a, se ha alcanzado el final del fichero, mientras que una l�nea en
blanco queda representada por '\n'
, una cadena que s�lo contiene
un salto de l�nea.
>>> f.readline() 'La primera l�nea del fichero.\012' >>> f.readline() 'La segunda l�nea del fichero\012' >>> f.readline() ''
f.readlines()
devuelve una lista que contiene todas las l�neas de datos del
fichero. Si se llama con un par�metro opcional sizehint (estimaci�n de tama�o), lee
los bytes indicados del fichero, sigue hasta completar una l�nea y devuelve la lista de
l�neas. Se suele utilizar esto para leer un fichero grande de una manera eficaz por l�neas,
pero sin tener que cargar en memoria el fichero entero. Todas las l�neas devueltas est�n
completas
>>> f.readlines() ['La primera l�nea del fichero.\012', 'La segunda l�nea del fichero\012']
f.write(cadena)
escribe el contenido de cadena al
fichero y devuelve None
.
>>> f.write('Probando, probando\n')
f.tell()
devuelve un entero que indica la posici�n actual
del objeto fichero dentro del fichero, medida en bytes desde el inicio
del fichero. Para cambiar la posici�n del objeto fichero se usa
"f.seek(desplazamiento, desde_d�nde)". La posici�n
se calcula sumando desplazamiento a un punto de referencia, seleccionado
por el argumento desde_d�nde. Un desde_d�nde cero mide desde el
inicio del fichero, 1 utiliza la posici�n actual y 2 utiliza el final del fichero
como punto de referencia. desde_d�nde se puede omitir, en cuyo caso se
utiliza el valor cero y se mide desde el principio del fichero.
>>> f=open('/tmp/fichTrabajo', 'r+') >>> f.write('0123456789abcdef') >>> f.seek(5) # Ir al 5� byte del fichero >>> f.read(1) '5' >>> f.seek(-3, 2) # Ir al 3er byte antes del final >>> f.read(1) 'd'
Cuando termines de usar un fichero, llama a f.close()
para cerrarlo
y liberar los recursos del sistema que utilice el fichero. Tras llamar a
f.close()
, fracasar� cualquier intento de usar el objeto fichero.
>>> f.close() >>> f.read() Traceback (innermost last): File "<stdin>", line 1, in ? ValueError: I/O operation on closed file
Los ficheros objeto tienen m�s m�todos, como isatty() y truncate(), de uso menos frecuente. Consulta la Referencia de las bibliotecas si deseas ver una gu�a completa de los objetos fichero.
Es f�cil escribir y leer cadenas de un fichero. Los n�meros exigen
un esfuerzo algo mayor, ya que el m�todo read() s�lo devuelve
cadenas, que tendr�n que pasarse a una funci�n como string.atoi(),
que toma una cadena como '123'
y devuelve su valor num�rico 123.
Sin embargo, cuando se quiere guardar tipos de datos m�s complejos, como
listas, diccionarios o instancias de clases, las cosas se complican bastante.
Mejor que hacer que los usuarios est�n constantemente escribiendo y depurando c�digo para guardar tipos de datos complejos, Python proporciona un m�dulo est�ndar llamado pickle7.1. Es un m�dulo asombroso que toma casi cualquier objeto de Python (�hasta algunas formas de c�digo Python!) y lo convierte a una representaci�n de cadena. Este proceso se llama estibado. Reconstruir el objeto a partir de la representaci�n en forma de cadena se llama desestibado. Entre el estibado y el desestibado, la cadena que representa el objeto puede ser almacenada en un fichero, en memoria o transmitirse por una conexi�n de red a una m�quina remota.
Si partes de un objeto x
y un objeto fichero f
previamente
abierto para escritura, el modo m�s sencillo de estibar el objeto
s�lo tiene una l�nea de c�digo:
pickle.dump(x, f)
Para realizar el proceso inverso, si f
es un objeto fichero
abierto para escritura:
x = pickle.load(f)
Existen otras variaciones de este tema, que se utilizan para estibar muchos objetos o si no se quiere escribir los datos estibados a un fichero. Se puede consultar la documentaci�n completa de pickle en la Referencia de las bibliotecas.
pickle es el m�todo est�ndar para hacer que los objetos Python se puedan almacenar y reutilizar en otros programas o futuras ejecuciones del mismo programa. El t�rmino t�cnico que identifica esto es objeto persistente. Como pickle se utiliza tanto, muchos autores que escriben extensiones a Python tienen cuidado de asegurarse de que los nuevos tipos de datos, tales como matrices, se estiben y desestiben de la manera adecuada.