Python 3 per a no programadors/Entrada-Sortida amb fitxers
Aquí hi ha un exemple senzill d'entrada/sortida (I/O) des de o cap a un fitxer:
# Escriure un fitxer
fitxer_sortida = open("prova.txt", "wt")
fitxer_sortida.write("Aquest text va cap a un fitxer extern\nMireu-lo i ho veureu!")
fitxer_sortida.close()
# Llegir un fitxer
fitxer_entrada = open("prova.txt", "rt")
text = fitxer_entrada.read()
fitxer_entrada.close()
print(text)
La sortida i els continguts del fitxer prova.txt
són:
Aquest text va cap a un fitxer extern Mireu-lo i ho veureu!
Fixeu-vos que ha escrit un fitxer anomenat prova.txt
al directori des d'on heu executat el programa. El \n
a la cadena de caràcters indica al llenguatge Python que cal posar un salt de línia (new line) al lloc on hi ha el \n
.
Una visió de conjunt del procés d'Entrada/sortida és:
- Obtenir un objecte de tipus fitxer amb la funció
open
. - Llegir o escriure a l'objecte de tipus fitxer (depenent de com s'ha obert)
- Tancar-lo
El primer pas és obtenir un objecte fitxer. La manera de fer-ho és fent servir la funció open
. El seu format és objecte_fitxer = open(nom_del_fitxer, mode)
on objecte_fitxer
és el nom de la variable on s'emmagatzemarà l'objecte de tipus fitxer, nom_del_fitxer
és una cadena amb el nom del fitxer, i mode
és "rt"
per llegir (read) el fitxer com a text o bé "wt"
per a escriure (write) el fitxer com a text (i uns quants més que ara ens saltarem). Tot seguit es poden invocar les funcions de l'objecte fitxer. Les dues funcions més frequents són: read
(llegir) i write
(escriure). La funció write
afegeix una cadena al final de fitxer. La funció read
llegeix el següent que troba al fitxer i ho retorna com una cadena. Si no se li dóna cap argument retornarà el fitxer sencer (tal com s'ha fet a l'exemple).
Tot seguit hi ha una nova versió del programa dels nombres de telèfon que s'ha fet a capítols anteriors:
def imprimeix_numeros(numeros):
print(u"Números de Telèfon:")
for k, v in números.items():
print("Nom:", k, u"\tNúmero:", v)
print()
def afegir_numero(numeros, nom, numero):
numeros[nom] = numero
def cercar_numero(numeros, nom):
if nom in numeros:
return u"El número és " + numeros[nom]
else:
return "no s'ha trobat " + nom
def treure_numero(numeros, nom):
if nom in numeros:
del numeros[nom]
else:
print("no s'ha trobat ", nom)
def carrega_numeros(numeros, nom_del_fitxer):
fitxer_entrada = open(nom_del_fitxer, "rt")
while True:
linia_entrada = fitxer_entrada.readline()
if not linia_entrada:
break
linia_entrada = linia_entrada[:-1]
nom, numero = linia_entrada.split(",")
numeros[nom] = numero
fitxer_entrada.close()
def grava_numeros(numeros, nom_del_fitxer):
fitxer_sortida = open(nom_del_fitxer, "wt")
for k, v in numeros.items():
fitxer_sortida.write(k + "," + v + "\n")
fitxer_sortida.close()
def imprimeix_menu():
print(u'1. Imprimir Números de Telèfon')
print(u'2. Afegir-hi un Número de Telèfon')
print(u'3. El·liminar-hi un Número de Telèfon')
print(u'4. Cercer un Número de Telèfon')
print(u'5. Carregar números')
print(u'6. Gravar números')
print(u'7. Sortir')
print()
llista_de_numeros = {}
tria_menu = 0
imprimeix_menu()
while True:
tria_menu = int(input("Escriviu un nombre (1-7): "))
if tria_menu == 1:
imprimeix_numeros(llista_de_numeros)
elif tria_menu == 2:
print(u"Afegir Nom i Número")
nom = input("Nom: ")
telefon = input(u"Número: ")
afegir_numero(llista_de_numeros, nom, telefon)
elif tria_menu == 3:
print(u"El·limnar Nom i Número")
nom = input("Nom: ")
treure_numero(llista_de_numeros, nom)
elif tria_menu == 4:
print(u"Cercar Númro")
nom = input("Nom: ")
print(cercar_numero(llista_de_numeros, nom))
elif tria_menu == 5:
nom_del fitxer = input("Nom del Fitxer a carregar: ")
carrega_numeros(llista_de_numeros, filename)
elif tria_menu == 6:
nom_del fitxer = input("Nom del fitxer on gravar-los: ")
save_numbers(llista_de_numeros, nom_del fitxer)
elif tria_menu == 7:
break
else:
imprimeix_menu()
print("Passi-ho bé")
Fixeu-vos que inclou gravar i carregar fitxers. Aquí hi ha alguns resultats d'executar-lo dues vegades:
1. Imprimir Números de Telèfon 2. Afegir-hi un Número de Telèfon 3. Eliminar-hi un Número de Telèfon 4. Cercer un Número de Telèfon 5. Carregar números 6. Gravar números 7. Sortir
Escriviu un nombre (1-7): 2 Afegir Nom i Número Nom: Jill Número: 1234
Escriviu un nombre (1-7): 2 Afegir Nom i Número Nom: Fred Número: 4321
Escriviu un nombre (1-7): 1 Números de Telèfon: Nom: Jill Número: 1234 Nom: Fred Número: 4321 Escriviu un nombre (1-7): 6 Nom del fitxer on gravar-los: nombres.txt Escriviu un nombre (1-7): 7 Passi-ho bé
1. Imprimir Números de Telèfon 2. Afegir-hi un Número de Telèfon 3. Eliminar-hi un Número de Telèfon 4. Cercer un Número de Telèfon 5. Carregar números 6. Gravar números 7. Sortir Escriviu un nombre (1-7): 5 Nom del Fitxer a carregar: nombres.txt Escriviu un nombre (1-7): 1 Números de Telèfon: Nom: Jill Número: 1234 Nom: Fred Número: 4321 Escriviu un nombre (1-7): 7 Passi-ho bé
Els bocins nous d'aquest programa són:
def carrega_numeros(numeros, nom_del_fitxer):
fitxer_entrada = open(nom_del_fitxer, "rt")
while True:
linia_entrada = fitxer_entrada.readline()
if not linia_entrada:
break
linia_entrada = linia_entrada[:-1]
nom, numero = linia_entrada.split(",")
numeros[nom] = numero
fitxer_entrada.close()
def grava_numeros(numeros, nom_del_fitxer):
fitxer_sortida = open(nom_del_fitxer, "wt")
for k, v in numeros.items():
fitxer_sortida.write(k + "," + v + "\n")
fitxer_sortida.close()
Primer observeu la part de gravar del programa. Primer crea un objecte de tipus fitxer amb la instrucció open(nom_de_fitxer, "wt")
. Tot segui crea una línia per a cada número de telèfon amb la instrucció fitxer_sortida.write(x + "," + numeros[x] + "\n")
. Això escriu una línia que conté el nom, una coma, el número i tot seguit un salt de línia.
La part de càrrega és una mica més complicada. Comença per obtenir un objecte de tipus fitxer. Llavors fa servir un bucle while True:
per anar repetint el procés fins que es trobi una instrucció break
. Llavors obté una línia amb la instrucció linia_entrada = fitxer_entrada.readline()
. la funció readline
retorna una cadena buida quan s'arriba a un final de fitxer. La instrucció if
ho vigila i quan això passa surt del bucle while
executant una instrucció break
. Esclar, si la funció readline
no retornés una codi newline al final de cada línia no hi hauria manera de saber si una cadena buida és una línia buida o el final del fitxer per tant es deixa el codi newline en el que retorna la instrucció readline
. Per tant cal eliminar-lo. La línia linia_entrada = linia_entrada[:-1]
fa precisament això a base de descartar l'últim caràcter. Llavors la línia nom, numero = linia_entrada.split(",")
parteix la línia al lloc on hi ha la coma en un nom i un número. Llavors això s'afegeix al diccionari numeros
.