Python: Entrada / Salida. Ficheros

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.

50 comentarios en «Python: Entrada / Salida. Ficheros»

  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. 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. Pingback: Entrada básica en Python

  4. 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.

  5. Pingback: Lectura Secuencial de Archivos con Python

  6. buen dia señores, sucede q estoy tratando de aprende python y estoy haciendo pruebas con el input y el raw_inputm, pero estoy teniendo problemas uso python 3.0 y cuando hago un a=input(«ingresar texto»), y luego if a == «bb» y el usuario ingreso «bb» no entra en el if no se a q se deba esto y con el raw_input, tengo el problema de que al querer correr el programa me dice NameError: name ‘raw_input’ is not defined y no e encontrado nada en la web para solucionar esto, de antemano gracias por el timpo, feliz dia.

    1. la funcion raw_input() ya no funciona en python 3, ahora solo es input() la cual captura datos en string, asi que si necesitas guardar un entero necesitaras usar la funcion int() o float().

      y el error que puede estar pasando es que no estas indentando bien el codigo…

  7. Pues deverías de ecplicar mas a fondo el uso de \n, para que sea de mayor utilidad para los leedores de estas paginas..

  8. hola,necesito que me ayuden con algo de python.
    estoy diseñando una simulacion de un sistema de archivos(file System) y lo que necesito es generar persistencia de datos y la idea que tuve es crear un txt por cada estructura que necesite guardar para cuando inicie nuevamente mi Simulacion de Sistema operativo.
    Por ejemplo, quiero generar un txt con la lista de usuarios, para cuando inicie nuevamente el SO no tenga q crear el usuario.
    Ahora mi problema es que al escribir el txt leyendo la lista de usuarios y escribiendo en el txt, me lo escribe todo en la misma linea y no hay espacios. Yo necesito que me ponga cada nombre de usuario en una linea para luego poder hacer bien la carga de datos en la variable de instancia del SO cuando lo vuelva a iniciar.
    Espero que se entienda!
    Muchas gracias por su tiempo!

  9. Hola estoy empezando a aprender python y tengo un problema tengo un codigo en donde pido el ingreso de 3 numeros. Lo que necesito es que esos numeros no sean letras…!!!! como puedo intente adaptar tu ejemplo:

    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»

    lo adapte pero no prosigue con el resto del codigo para que pueda seguir con el programa no se porque. Aca te dejo el codigo a ver que me podes decir…..

    desde ya muchas gracias por tu tiempo….

    saludos

    #Enunciado

    print ‘El siguiente programa solucionara el polinomio de segundo grado ax2 + bx + c = 0’

    #Entrada de Datos

    try:
    a =float(raw_input(‘Ingrese el coeficiente a: ‘))
    except ValueError:
    print ‘debes ingrear un numero’

    try:
    b =float(raw_input(‘Ingrese el coeficiente b: ‘))
    except ValueError:
    print ‘debes ingrear un numero’

    try:
    c =float(raw_input(‘Ingrese el coeficiente c: ‘))
    except ValueError:
    print ‘debes ingrear un numero’

    #Validar A

    if a != 0:
    #Calculos
    radicando = b**2-(4*a*c)
    divisor = 2*a

    #Validar radicando

    if radicando >= 0:
    x1 = (-b+(radicando)**0.5)/(divisor)
    x2 = (-b-(radicando)**0.5)/(divisor)

    #Presentacion

    print ‘El valor de la raiz x1 es: ‘,x1
    print ‘El valor de la raiz x2 es: ‘,x2

    else:

    print ‘El polinomio posee raices imaginarias’

    else:

    1. Yo también hace rato que estoy programando en python, e hice también un pequeño programa para calcular bascara… te recomiendo que todos los procedimientos los incluyas dentro de una solo función, y en caso de error, sólo vuelvas a llamar a la función…
      en ratos libres estoy mejorando el trabajo con los numeros complejos…
      También creo que podrías solucionar el tema del chequeo de valores asignados a variables con un bucle infinito (otro buen recurso en python)… espero que te sirva de algo esto que te escribo!! y agrdezco por el libro a Raúl Gonzalez Duque que me sirvió mucho para arrancar con el lenguaje

  10. Hola, quiero escribir el valor de una variable en un archivo de texto. Esta es la sentencia que escribo:

    self.gr_file_sink_0 = gr.file_sink(gr.sizeof_gr_complex*1, «/home/Desktop/out.dat»)

    self.tb.connect((variable, 0), self.gr_file_sink_0, 0))

    Me da un error que no entiendo, le he dado muchas vueltas y no se donde esta el error. Estas dos lineas las introduzco dentro del archivo qa_atsc.py de GNURadio. Simplemente lo que quiero es guardar el valor de una variable en un archivo de texto.

    Gracias

  11. Tengo un problema no puedo escribir ni eñes ni tildes en los documentos que se guardan. Cómo puedo hacerlo amigo.

    def escribir_en_consola(ruta):
    texto = u»»
    while texto != «salir»:
    texto = raw_input()
    if texto != «salir»:
    t=open(ruta,»a»)
    t.write(texto + «\n»)
    t.close()

  12. Hola…

    Tengo una duda necesito cambiar un grupo de archivos de nombre, ¿Cómo puedo yo desde el directorio donde estoy entrar a la dirección donde tengo los archivos, leerlos y tomar solo los archivos especificos que necesito para renombrarlos y pasarlos a otra carpeta?

    Ejemplo

    tengo una carpeta que se llama data en ella tengo archivos del siguiente tipo

    a1.data, a1p.data, a2.data, a2p.data, etc…
    quiero solo leer los a1.data …an.data los que tienen la p no me interesan, luego esos archivos quiero renombrarlos por ejemplo por 181.in, 182.in, etc y grabarlos en una nueva carpeta…

    Agradeceria mucho una mano ya que soy nuevo en esto de programar en python

    gracias

  13. Hola.
    Tengo un problema no se resolver el siguiente ejercicio en el python 3.0, espero que me lo podais resolver he realizado algo a borrador y creo q esta mal. Muchas Gracias.

    Se propone construir un programa en Phython que acceda a un fichero de texto e imprima la línea más parecida a un conjunto de términos de búsqueda. Los términos de búsqueda serán especificados en una única cadena q, utilizando el espacio en blanco como separador. La línea seleccionada podría contener todos o tan sólo algunos de los términos de búsqueda. El fichero de texto objeto de las búsquedas ( noticias.txt) se adjuntan a este enunciado. En todo caso, el programa debería funcionar sobre cualquier fichero de texto.

  14. Hola alguien sabe como le puedo hacer para pueda seleccionar mas de un archivo de forma interactiva pero que los nombres de los archivos vayan cambiando automaticamente a través de codigo python, ya logre la lectura y procesamiento de un archivo fijo pero necesito habrir varios en una sola ejecucion

    1. Puedes crear una variable tipo string con los nombres de los archivos (podrías usar indices de una lista para generar nombres en secuencia)
      despues pasas esa variable como argumento para open.
      eso me ha servido para trabajar con un gran numero de archivos con nombres similares
      for i in lista
      nombre=’comun’+str(i)
      file=open(nombre,’r’)
      operaciones…

  15. Hola,
    Tengo un problema con la funcion raw_input.
    Yo debo leer un archivo que es definido por el usuario asi que escribi el siguiente codigo :

    import math
    import sys
    «»»from numpy import *»»»

    input_file=input(«Please enter the name of the report you wish to analyse:»);
    originaltxt_fresh= open(inputfile,»r»);
    original=originaltxt_fresh.read();
    originaltxt_fresh.close();
    print originaltxt_fresh;

    Pero al lanzar el codigo se genera el siguiente error:

    Traceback (most recent call last):
    File»C:/Archivos_temporales_station_unix/eje2.py», line 7, in
    originaltxt_fresh= open(inputfile,»r»);
    NameError: name ‘inputfile’ is not defined

    Pordian decirme cual es el error?

    Gracias

  16. PORFAVOR alguien ayudeme, necesito abrir un archivo.txt y que cuando cierre el programa, se modifique alguien tiene el codigopara eso?

  17. Pingback: Aceptando parametros desde la linea de comandos

  18. Hay algun método que detecte la posicion de una palabra concreta para escribir al lado? Me refiero sin tener que recurrir a un «if».

    Gracias por el tutorial!

  19. Hola! Tengo una pregunta. Sabemos que python tiene dos palabras reservadas para crear objetos fichero. open() y file() ambas aceptan los mismos parámetros y devuelven, a mi entender, lo mismo. Entonces, cual es la diferencia?

  20. Hola! Resulta que estoy haciedo un programita que guarde unos objetos (libros) que he creado, en un fichero serializandolo con pickle hasta aqui todo bien pero para mostrarlos tengo problemas si alguien me puede giar se lo agradeceria.
    Funcion que recibe el nombre del archivo y una lista que es cargada con la funcion descerializar.

    def des_serializar(self,nombre):
    try:
    lista=[]
    fichero = open(nombre, «rb»)
    while True:
    obj= pickle.load(fichero)
    lista.append(obj)
    except:
    pass
    fichero.close()
    return lista

    def listar_todos(nombre,lista):
    obj=CSerializar.CSerializar()
    lista= obj.des_serializar(nombre)
    for objetos in lista:
    print «———————-»
    print objetos.devolver_isbn()
    print objetos.devolver_titulo()
    print objetos.devolver_autor()
    print objetos.devolver_editorial()
    print «———————-«

  21. tutoriales currados??? pero si no son suyos, estan en pdf y es de un libro que se llama python para todos pero bueno, es un buen aporte

  22. como puedo hacer para guardar algo en un .txt y que si abro el txt se vea algo asi
    [[elemento,de,la,lista,1]
    [elemento,de,la,lista,2]
    [elemento,de,la,lista,3]]

    agradezco la ayuda

  23. hola necesito resolver este algoritmo en python y escribir el analisis y pseudocodigo algoritmo que lea el dato N de tipo entero y muestre el resultado de la expresión lógica N < 10 | | N < 30.

  24. ME PUEDEN DAR LA RESPUESTA DE ESTE ALGORITMO un algoritmo que lea los datos enteros A , B y C y muestre el resultado de la expresión lógica A * C >= ( B – 10)

  25. buenas, tengo que hacer un indice de un archivo en pyhton con eclipse. Primero tengo que leer el archivo.
    Lo bajé está en UTF-8 lo coloqué en la carpeta del programa que estoy haciendo pero no lo encuentra.
    Por otro lado como hago para luego de leerlo parsearlo?
    Yo me bajé Ntlk que leí que era recomendable usarlo

    espero sus respuestas
    gracias

  26. Hola! La verdad te felicito y agradezco por compartir tus conocimientos y por esforzarte en ser lo mas claro posible.
    Todavia sigo leyendo el tutorial de «Python para todos» y esta muy bueno, ademas es entendible y muy bien explicado.
    Gracias hermano, gracias por este esfuerzo.
    Un saludo y un abrazo.

    Atte: ArgentinaIRC!

  27. ¿Cual es la diferencia entre file() y open(), no he encontrado la de file() pero por lo visto funciona de la misma forma que open(), podrías explicarlo? muchas gracias!

  28. Esta muy bien explicado este tutorial, gracias.
    Tengo una situacion, con unos archivos .DAT creados con Phyton pero no hay adicionales que indiquen la estructura de ellos (.DEF, etc), ya use varias utilerias entre ellas btfiler y solo veo parte de la informacion (ASCII) y el resto en codigo no leible, hay forma de recuperar el contenido de estos archivos. El sistema los visualiza correctamente, pero ya son muy grandes y se requiere respaldarlos y desde el sistema no se puede hacer.

  29. Hola buenas, tengo una duda, ya que estoy preprando un programilla y me he quedado astascado porque me gustaria encontrar la manera de crear un archivo cuyo nombre sea el de una variable y no se como hacerlo.

    variable = raw_input()

    if valor == 2 :
    notes = open(«notes(variable).txt»,»a+»)
    contingut = notes.read()
    final_de_notes = notes.tell()
    notes.write(«Funciona»)
    notes.seek(final_de_notes)
    nou_contingut = notes.read()
    notes.close()
    Print «Logrado»

    Este es el fragmento de codigo que me da problemas, por favor si alguien me puede ayudar, me interesaría poner el valor de «variable» como nombre el archivo que voy a abrir/crear.

    Muchas gracias

  30. hola como hago para que una vez que ejecuto el codigo en la consola se guarde todos los valores que asigno el usuario , para que la próxima vez que se ejecute tengas los mismos valores que le asigno el usuario a el programa y puedan ser utilizados nuevamente , por ejemplo algo así como tus gastos son 300 y se finaliza el programa y al ejecutarlo de nuevo en el principio que la variable gastos tenga el valor anterior de 300

Responder a Daniel Cancelar respuesta

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.