Python: Entrada / Salida. Ficheros

« Estadísticas Marzo 2008 | Firefox 3 beta 5 »

Nuestros programas serían de muy poca utilidad si no fueran capaces de interaccionar con el usuario. En capítulos anteriores vimos, de pasada, el uso de la palabra clave print para mostrar mensajes en pantalla.

En esta lección, además de describir más detalladamente del uso de print para mostrar mensajes al usuario, aprenderemos a utilizar las funciones input y raw_input para pedir información, así como los argumentos de línea de comandos y, por último, la entrada/salida de ficheros.

Entrada estándar

La forma más sencilla de obtener información por parte del usuario es mediante la función raw_input. Esta función toma como parámetro una cadena a usar como prompt (es decir, como texto a mostrar al usuario pidiendo la entrada) y devuelve una cadena con los caracteres introducidos por el usuario hasta que pulsó la tecla Enter. Veamos un pequeño ejemplo:

nombre = raw_input("Como te llamas? ")
print "Encantado, " + nombre

Si necesitáramos un entero como entrada en lugar de una cadena, por ejemplo, podríamos utilizar el constructor de int para convertir la cadena a entero, aunque sería conveniente tener en cuenta que puede lanzarse una excepción si lo que introduce el usuario no es un número.

try:
    edad = raw_input("Cuantos anyos tienes? ")
    dias = int(edad) * 365
    print "Has vivido " + str(dias) + " dias"
except ValueError:
    print "Eso no es un numero"

La función input es un poco más complicada. Lo que hace esta función es utilizar raw_input para leer una cadena de la entrada estándar, y después pasa a evaluarla como si de código Python se tratara; por lo tanto input debería tratarse con sumo cuidado.

Parámetros de línea de comando

Además del uso de input y raw_input el programador Python cuenta con otros métodos para obtener datos del usuario. Uno de ellos es el uso de parámetros a la hora de llamar al programa en la línea de comandos. Por ejemplo:

python editor.py hola.txt

En este caso hola.txt sería el parámetro, al que se puede acceder a través de la lista sys.argv, aunque, como es de suponer, antes de poder utilizar dicha variable debemos importar el módulo sys. sys.argv[0] contiene siempre el nombre del programa tal como lo ha ejecutado el usuario, sys.argv[1], si existe, sería el primer parámetro; sys.argv[2] el segundo, y así sucesivamente.

import sys

if(len(sys.argv) > 1):
    print "Abriendo " + sys.argv[1]
else:
    print "Debes indicar el nombre del archivo"

Existen módulos, como optparse, que facilitan el trabajo con los argumentos de la línea de comandos, pero explicar su uso queda fuera del objetivo de esta lección.

Salida estándar

La forma más sencilla de mostrar algo en la salida estándar es mediante el uso de la sentencia print, como hemos visto multitud de veces en ejemplos anteriores. En su forma más básica a la palabra clave print le sigue una cadena, que se mostrará en la salida estándar al ejecutarse el estamento.

>>> print "Hola mundo"
Hola mundo

Después de imprimir la cadena pasada como parámetro el puntero se sitúa en la siguiente línea de la pantalla, por lo que el print de Python funciona igual que el println de Java.

En algunas funciones equivalentes de otros lenguajes de programación es necesario añadir un carácter de nueva línea para indicar explícitamente que queremos pasar a la siguiente línea. Este es el caso de la función printf de C o la propia función print de Java.

Ya explicamos el uso de estos caracteres especiales en su día durante la explicación del tipo cadena de la lección Python: Tipos básicos. La siguiente sentencia, por ejemplo, imprimiría la palabra "Hola", seguida de un renglón vacío (dos caracteres de nueva línea, '\n'), y a continuación la palabra "mundo" indentada (un carácter tabulador, '\t').

print "Hola\n\n\tmundo"

Para que la siguiente impresión se realizara en la misma línea tendríamos que colocar una coma al final de la sentencia. Comparemos el resultado de este código:

>>> for i in range(3):
>>> …print i,
0 1 2

Con el de este otro, en el que no utiliza una coma al final de la sentencia:

>>> for i in range(3):
>>> …print i
0
1
2

Este mecanismo de colocar una coma al final de la sentencia funciona debido a que es el símbolo que se utiliza para separar cadenas que queramos imprimir en la misma línea.

>>> print "Hola", "mundo"
Hola mundo

Esto se diferencia del uso del operador '+' para concatenar las cadenas en que al utilizar las comas print introduce automáticamente un espacio para separar cada una de las cadenas. Este no es el caso al utilizar el operador +, ya que lo que le llega a print es un solo argumento: una cadena ya concatenada.

>>> print "Hola" + "mundo"
Holamundo

Además, al utilizar el operador + tendríamos que convertir antes cada argumento en una cadena de no serlo ya, ya que no es posible concatenar cadenas y otros tipos, mientras que al usar el primer método no es necesaria la conversión.

>>> print "Cuesta", 3, "euros"
Cuesta 3 euros
>>> print "Cuesta" + 3 + "euros"
<type 'exceptions.TypeError'>: cannot concatenate 'str' and 'int' objects

La sentencia print, o más bien las cadenas que imprime, permiten también utilizar técnicas avanzadas de formateo, de forma similar al sprintf de C. Veamos un ejemplo bastante simple:

print "Hola %s" % "mundo"
print "%s %s" % ("Hola", "mundo")

Lo que hace la primera línea es introducir los valores a la derecha del símbolo '%' (la cadena "mundo") en las posiciones indicadas por los especificadores de conversión de la cadena a la izquierda del símbolo '%', tras convertirlos al tipo adecuado.

En el segundo ejemplo, vemos cómo se puede pasar más de un valor a sustituir, por medio de una tupla.

En este ejemplo sólo tenemos un especificador de conversión: '%s'.

Los especificadores más sencillos están formados por el símbolo '%' seguido de una letra que indica el tipo con el que formatear el valor. Por ejemplo:

Especificador Formato
%s Cadena
%d Entero
%o Octal
%x Hexadecimal
%f Real

Se puede introducir un número entre el '%' y el carácter que indica el tipo al que formatear, indicando el número mínimo de caracteres que queremos que ocupe la cadena. Si el tamaño de la cadena resultante es menor que este número, se añadirán espacios a la izquierda de la cadena. En el caso de que el número sea negativo, ocurrirá exactamente lo mismo, sólo que los espacios se añadirán a la derecha de la cadena.

>>> print "%10s mundo" % "Hola"
______Hola mundo
>>> print "%-10s mundo" % "Hola"
Hola_______mundo

En el caso de los reales es posible indicar la precisión a utilizar precediendo la 'f' de un punto seguido del número de decimales que queremos mostrar:

>>> from math import pi
>>> print "%.4f" % pi
3.1416

La misma sintaxis se puede utilizar para indicar el número de caracteres de la cadena que queremos mostrar

>>> print "%.4s" % "hola mundo"
hola

Archivos

Los ficheros en Python son objetos de tipo file creados mediante la función open (abrir). Esta función toma como parámetros una cadena con la ruta al fichero a abrir, que puede ser relativa o absoluta; una cadena opcional indicando el modo de acceso (si no se especifica se accede en modo lectura) y, por último, un entero opcional para especificar un tamaño de buffer distinto del utilizado por defecto.

El modo de acceso puede ser cualquier combinación lógica de los siguientes modos:

  • 'r': read, lectura. Abre el archivo en modo lectura. El archivo tiene que existir previamente, en caso contrario se lanzará una excepción de tipo IOError.
  • 'w': write, escritura. Abre el archivo en modo escritura. Si el archivo no existe se crea. Si existe, sobreescribe el contenido.
  • 'a': append, añadir. Abre el archivo en modo escritura. Se diferencia del modo 'w' en que en este caso no se sobreescribe el contenido del archivo, sino que se comienza a escribir al final del archivo.
  • 'b': binary, binario.
  • '+': permite lectura y escritura simultáneas.
  • 'U': universal newline, saltos de línea universales. Permite trabajar con archivos que tengan un formato para los saltos de línea que no coincide con el de la plataforma actual (en Windows se utiliza el caracter CR LF, en Unix LF y en Mac OS CR).
f = open("archivo.txt", "w")

Tras crear el objeto que representa nuestro archivo mediante la función open podremos realizar las operaciones de lectura/escritura pertinentes utilizando los métodos del objeto que veremos en las siguientes secciones.

Una vez terminemos de trabajar con el archivo debemos cerrarlo utilizando el método close.

Lectura de archivos

Para la lectura de archivos se utilizan los métodos read, readline y realines.

El método read devuelve una cadena con el contenido del archivo o bien el contenido de los primeros n bytes, si se especifica el tamaño máximo a leer.

completo = f.read()

parte = f2.read(512)

El método readline sirve para leer las líneas del fichero una por una. Es decir, cada vez que se llama a este método, se devuelve el contenido del archivo desde el puntero hasta que se encuentra un carácter de nueva línea, incluyendo este carácter.

while True:
      linea = f.readline()
      if not linea: break
      print line

Por último, readlines, funciona leyendo todas las líneas del archivo y devolviendo una lista con las líneas leídas.

Escritura de archivos

Para la escritura de archivos se utilizan los método write y writelines. Mientras el primero funciona escribiendo en el archivo una cadena de texto que toma como parámetro, el segundo toma como parámetro una lista de cadenas de texto indicando las líneas que queremos escribir en el fichero.

Mover el puntero de lectura/escritura en ficheros

Hay situaciones en las que nos puede interesar mover el puntero de lectura/escritura a una posición determinada del archivo. Por ejemplo si queremos empezar a escribir en una posición determinada y no al final o al principio del archivo.

Para esto se utiliza el método seek que toma como parámetro un número positivo o negativo a utilizar como desplazamiento. También es posible utilizar un segundo parámetro para indicar desde dónde queremos que se haga el desplazamiento: 0 indicará que el desplazamiento se refiere al principio del fichero (comportamiento por defecto), 1 se refiere a la posición actual, y 2, al final del fichero.

Para determinar la posición en la que se encuentra actualmente el puntero se utiliza el método tell, que devuelve un entero indicando la distancia en bytes desde el principio del fichero.

Relacionadas

Comentarios
  1. Menudos tutoriales de python que te estás currando. Mis felicitaciones y las gracias, ya que los estoy siguiendo y me están siendo de mucha utilidad.
    Saludos!

  2. guillem

    Magnífico todos los artículos sobre python, muy claros e instructivos. Gracias!

    Solo quería comentar que estaría bien, sobretoto pensando en python 3000 que se comentara que el comando "print" va a cambiar bastante y que el actual no funcionará.

  3. [...] aquí, vía Mundo Geek. En adelante mi breve [...]

  4. Mil zenkius!!

  5. Pues si, a Guido no le gusta demasiado el print actual. Lo ve como un hack bastante feo, aunque es de lo más útil.

    Ya comentaré cambios y modificaré entradas cuando salga Python 3000.

  6. [...] Basado en el tutorial original de MundoGeek [...]

Deja un comentario