Python Language
Archivos y carpetas I / O
Buscar..
Introducción
Cuando se trata de almacenar, leer o comunicar datos, trabajar con los archivos de un sistema operativo es tanto necesario como fácil con Python. A diferencia de otros idiomas en los que la entrada y salida de archivos requiere objetos complejos de lectura y escritura, Python simplifica el proceso, ya que solo necesita comandos para abrir, leer / escribir y cerrar el archivo. Este tema explica cómo Python puede interactuar con archivos en el sistema operativo.
Sintaxis
- file_object = open (filename [, access_mode] [, buffering])
Parámetros
Parámetro | Detalles |
---|---|
nombre del archivo | la ruta a su archivo o, si el archivo está en el directorio de trabajo, el nombre de archivo de su archivo |
modo de acceso | un valor de cadena que determina cómo se abre el archivo |
amortiguación | un valor entero utilizado para el búfer de línea opcional |
Observaciones
Evitar el infierno de codificación multiplataforma
Cuando se utiliza el open()
incorporado de Python, es una buena práctica pasar siempre el argumento de encoding
, si pretende que su código se ejecute en varias plataformas. El motivo de esto es que la codificación predeterminada de un sistema difiere de una plataforma a otra.
Si bien los sistemas linux
sí usan utf-8
como predeterminado, esto no es necesariamente cierto para MAC y Windows.
Para verificar la codificación predeterminada de un sistema, intente esto:
import sys
sys.getdefaultencoding()
de cualquier intérprete de python.
Por lo tanto, es aconsejable siempre sepcificar una codificación, para asegurarse de que las cadenas con las que está trabajando estén codificadas como lo que cree que son, lo que garantiza la compatibilidad entre plataformas.
with open('somefile.txt', 'r', encoding='UTF-8') as f:
for line in f:
print(line)
Modos de archivo
Hay diferentes modos con los que puede abrir un archivo, especificados por el parámetro de mode
. Éstos incluyen:
'r'
- modo de lectura. El valor por defecto. Le permite solo leer el archivo, no modificarlo. Al usar este modo el archivo debe existir.'w'
- modo de escritura. Creará un nuevo archivo si no existe, de lo contrario borrará el archivo y le permitirá escribir en él.'a'
- modo de añadir. Escribirá los datos al final del archivo. No borra el archivo, y el archivo debe existir para este modo.'rb'
- modo de lectura en binario. Esto es similar ar
excepto que la lectura se fuerza en modo binario. Esta es también una opción por defecto.'r+'
- modo de lectura más modo de escritura al mismo tiempo. Esto le permite leer y escribir en archivos al mismo tiempo sin tener que usarr
yw
.'rb+'
- modo de lectura y escritura en binario. Lo mismo quer+
excepto que los datos están en binario'wb'
- modo de escritura en binario. Lo mismo quew
excepto que los datos están en binario.'w+'
- modo de escritura y lectura. Exactamente igual quer+
pero si el archivo no existe, se crea uno nuevo. De lo contrario, el archivo se sobrescribe.'wb+'
- modo de escritura y lectura en modo binario. Lo mismo quew+
pero los datos están en binario.'ab'
- añadiendo en modo binario. Similar aa
excepto que los datos están en binario.'a+'
- modo de añadir y leer. Similar aw+
ya que creará un nuevo archivo si el archivo no existe. De lo contrario, el puntero del archivo se encuentra al final del archivo, si existe.'ab+'
- modo de añadir y leer en binario. Lo mismo quea+
excepto que los datos están en binario.with open(filename, 'r') as f: f.read() with open(filename, 'w') as f: f.write(filedata) with open(filename, 'a') as f: f.write('\n' + newdata)
r | r + | w | w + | una | a + | |
---|---|---|---|---|---|---|
Leer | ✔ | ✔ | ✘ | ✔ | ✘ | ✔ |
Escribir | ✘ | ✔ | ✔ | ✔ | ✔ | ✔ |
Crea archivo | ✘ | ✘ | ✔ | ✔ | ✔ | ✔ |
Borrar archivo | ✘ | ✘ | ✔ | ✔ | ✘ | ✘ |
Posición inicial | comienzo | comienzo | comienzo | comienzo | Fin | Fin |
Python 3 agregó un nuevo modo para la exclusive creation
para que no truncas o sobrescribas accidentalmente un archivo existente.
-
'x'
- abierto para creación exclusiva, generaráFileExistsError
si el archivo ya existe -
'xb'
- abierto para el modo de escritura de creación exclusiva en binario. Lo mismo quex
excepto que los datos están en binario. -
'x+'
- modo de lectura y escritura. Similar aw+
ya que creará un nuevo archivo si el archivo no existe. De lo contrario, se levantaráFileExistsError
. -
'xb+'
- modo de escritura y lectura. Exactamente lo mismo quex+
pero los datos son binarios.
X | x + | |
---|---|---|
Leer | ✘ | ✔ |
Escribir | ✔ | ✔ |
Crea archivo | ✔ | ✔ |
Borrar archivo | ✘ | ✘ |
Posición inicial | comienzo | comienzo |
Permita que uno escriba su código de archivo abierto de una manera más pitónica:
try:
with open("fname", "r") as fout:
# Work with your open file
except FileExistsError:
# Your error handling goes here
En Python 2 habrías hecho algo como
import os.path
if os.path.isfile(fname):
with open("fname", "w") as fout:
# Work with your open file
else:
# Your error handling goes here
Leyendo un archivo línea por línea
La forma más sencilla de iterar sobre un archivo línea por línea:
with open('myfile.txt', 'r') as fp:
for line in fp:
print(line)
readline()
permite un control más granular sobre la iteración línea por línea. El siguiente ejemplo es equivalente al de arriba:
with open('myfile.txt', 'r') as fp:
while True:
cur_line = fp.readline()
# If the result is an empty string
if cur_line == '':
# We have reached the end of the file
break
print(cur_line)
Usar el iterador de bucle for y readline () juntos se considera una mala práctica.
Más comúnmente, el método readlines()
se usa para almacenar una colección iterable de las líneas del archivo:
with open("myfile.txt", "r") as fp:
lines = fp.readlines()
for i in range(len(lines)):
print("Line " + str(i) + ": " + line)
Esto imprimiría lo siguiente:
Línea 0: hola
Línea 1: mundo
Obtener el contenido completo de un archivo
El método preferido para el archivo i / o es usar la palabra clave with
. Esto asegurará que el identificador de archivo se cierre una vez que se haya completado la lectura o escritura.
with open('myfile.txt') as in_file:
content = in_file.read()
print(content)
o, para manejar el cierre del archivo de forma manual, se puede renunciar with
y simplemente llamar a close
a sí mismo:
in_file = open('myfile.txt', 'r')
content = in_file.read()
print(content)
in_file.close()
Tenga en cuenta que sin utilizar una instrucción with
, puede mantener el archivo abierto por accidente en caso de que surja una excepción inesperada:
in_file = open('myfile.txt', 'r')
raise Exception("oops")
in_file.close() # This will never be called
Escribiendo en un archivo
with open('myfile.txt', 'w') as f:
f.write("Line 1")
f.write("Line 2")
f.write("Line 3")
f.write("Line 4")
Si abres myfile.txt
, verás que su contenido es:
Línea 1Línea 2Línea 3Línea 4
Python no agrega automáticamente saltos de línea, debe hacerlo manualmente:
with open('myfile.txt', 'w') as f:
f.write("Line 1\n")
f.write("Line 2\n")
f.write("Line 3\n")
f.write("Line 4\n")
Línea 1
Línea 2
Línea 3
Linea 4
No use os.linesep
como terminador de línea al escribir archivos abiertos en modo de texto (el valor predeterminado); use \n
lugar.
Si desea especificar una codificación, simplemente agregue el parámetro de encoding
a la función de open
:
with open('my_file.txt', 'w', encoding='utf-8') as f:
f.write('utf-8 text')
También es posible utilizar la declaración de impresión para escribir en un archivo. La mecánica es diferente en Python 2 vs Python 3, pero el concepto es el mismo en que puedes tomar la salida que habría ido a la pantalla y enviarla a un archivo.
with open('fred.txt', 'w') as outfile:
s = "I'm Not Dead Yet!"
print(s) # writes to stdout
print(s, file = outfile) # writes to outfile
#Note: it is possible to specify the file parameter AND write to the screen
#by making sure file ends up with a None value either directly or via a variable
myfile = None
print(s, file = myfile) # writes to stdout
print(s, file = None) # writes to stdout
En Python 2 habrías hecho algo como
outfile = open('fred.txt', 'w')
s = "I'm Not Dead Yet!"
print s # writes to stdout
print >> outfile, s # writes to outfile
A diferencia de usar la función de escritura, la función de impresión agrega automáticamente saltos de línea.
Copiando los contenidos de un archivo a un archivo diferente
with open(input_file, 'r') as in_file, open(output_file, 'w') as out_file:
for line in in_file:
out_file.write(line)
- Usando el módulo de
shutil
:
import shutil
shutil.copyfile(src, dst)
Compruebe si existe un archivo o ruta
Emplea el estilo de codificación EAFP e try
abrirlo.
import errno
try:
with open(path) as f:
# File exists
except IOError as e:
# Raise the exception if it is not ENOENT (No such file or directory)
if e.errno != errno.ENOENT:
raise
# No such file or directory
Esto también evitará condiciones de carrera si otro proceso eliminó el archivo entre la verificación y cuando se utiliza. Esta condición de carrera podría ocurrir en los siguientes casos:
Usando el módulo
os
:import os os.path.isfile('/path/to/some/file.txt')
Utilizando
pathlib
:import pathlib path = pathlib.Path('/path/to/some/file.txt') if path.is_file(): ...
Para verificar si existe una ruta determinada o no, puede seguir el procedimiento anterior de EAFP o verificar explícitamente la ruta:
import os
path = "/home/myFiles/directory1"
if os.path.exists(path):
## Do stuff
Copiar un árbol de directorios
import shutil
source='//192.168.1.2/Daily Reports'
destination='D:\\Reports\\Today'
shutil.copytree(source, destination)
El directorio de destino no debe existir ya.
Iterar archivos (recursivamente)
Para iterar todos los archivos, incluidos los subdirectorios, use os.walk:
import os
for root, folders, files in os.walk(root_dir):
for filename in files:
print root, filename
root_dir puede ser "." para comenzar desde el directorio actual, o cualquier otra ruta desde la que comenzar.
Si también desea obtener información sobre el archivo, puede usar el método más eficiente os.scandir así:
for entry in os.scandir(path):
if not entry.name.startswith('.') and entry.is_file():
print(entry.name)
Leer un archivo entre un rango de líneas.
Supongamos que desea iterar solo entre algunas líneas específicas de un archivo
Puedes hacer uso de itertools
para eso.
import itertools with open('myfile.txt', 'r') as f: for line in itertools.islice(f, 12, 30): # do something here
Esto leerá las líneas 13 a 20, ya que la indexación de Python comienza desde 0. Por lo tanto, la línea número 1 se indexa como 0
Como también puede leer algunas líneas adicionales haciendo uso de la next()
palabra clave next()
aquí.
Y cuando esté utilizando el objeto de archivo como un iterable, no use la instrucción readline()
aquí ya que las dos técnicas para atravesar un archivo no deben mezclarse
Acceso aleatorio a archivos usando mmap
El uso del módulo mmap
permite al usuario acceder aleatoriamente a las ubicaciones de un archivo asignando el archivo a la memoria. Esta es una alternativa al uso de operaciones de archivos normales.
import mmap
with open('filename.ext', 'r') as fd:
# 0: map the whole file
mm = mmap.mmap(fd.fileno(), 0)
# print characters at indices 5 through 10
print mm[5:10]
# print the line starting from mm's current position
print mm.readline()
# write a character to the 5th index
mm[5] = 'a'
# return mm's position to the beginning of the file
mm.seek(0)
# close the mmap object
mm.close()
Reemplazo de texto en un archivo
import fileinput
replacements = {'Search1': 'Replace1',
'Search2': 'Replace2'}
for line in fileinput.input('filename.txt', inplace=True):
for search_for in replacements:
replace_with = replacements[search_for]
line = line.replace(search_for, replace_with)
print(line, end='')
Comprobando si un archivo está vacío
>>> import os
>>> os.stat(path_to_file).st_size == 0
o
>>> import os
>>> os.path.getsize(path_to_file) > 0
Sin embargo, ambos lanzarán una excepción si el archivo no existe. Para evitar tener que atrapar tal error, haga esto:
import os
def is_empty_file(fpath):
return os.path.isfile(fpath) and os.path.getsize(fpath) > 0
que devolverá un valor bool
.