Este tutorial tiene un curso de video relacionado creado por el equipo de Real Python. Míralo junto con el tutorial escrito para profundizar tu comprensión: Recetas prácticas para trabajar con archivos en Python

Python tiene varios módulos incorporados y funciones para manejar archivos. Estas funciones se distribuyen en varios módulos, tales comoos,os.path,shutil, pathlib, por nombrar algunos. Este artículo reúne en un solo lugar muchas de las funciones que necesita saber para realizar las operaciones más comunes en archivos en Python.

En este tutorial, aprenderás a:

  • Recuperar propiedades de archivo
  • Crear directorios
  • Patrones de coincidencia en nombres de archivo
  • Árboles de directorio de Traverse
  • Crear archivos y directorios temporales
  • Eliminar archivos y directorios
  • Copiar, mover o renombrar archivos y directorios
  • Crear y extraer archivos ZIP y TAR
  • Abra varios archivos con elfileinputmódulo

Bono gratuito: 5 pensamientos sobre la maestría de Python, un curso gratuito para desarrolladores de Python que te muestra la hoja de ruta y la mentalidad que necesitarás para llevar tus habilidades de Python al siguiente nivel.

Python’s “with open(…) as …” Patrón

Leer y escribir datos en archivos usando Python es bastante sencillo. Para hacer esto, primero debe abrir los archivos en el modo apropiado. Aquí hay un ejemplo de cómo usar el patrón de Python «con open(…) como …» para abrir un archivo de texto y leer su contenido:

with open('data.txt', 'r') as f:
    data = f.read()

open()toma un nombre de archivo y un modo como sus argumentos.rabre el archivo en modo de solo lectura. Para escribir datos en un archivo, pasewComo argumento en su lugar:

with open('data.txt', 'w') as f:
    data = 'some data to be written to the file'
    f.write(data)

En los ejemplos anteriores,open()abre archivos para leer o escribir y devuelve un manejador de archivos (fen este caso) que proporciona métodos que se pueden usar para leer o escribir datos en el archivo. Consulte Lectura y escritura de archivos en Python y Trabajo con E/S de archivos en Python para obtener más información sobre cómo leer y escribir en archivos.

Obtener una lista de directorios

Supongamos que su directorio de trabajo actual tiene un subdirectorio llamadomy_directoryque tiene los siguientes contenidos:

my_directory/
|
├── sub_dir/
|   ├── bar.py
|   └── foo.py
|
├── sub_dir_b/
|   └── file4.txt
|
├── sub_dir_c/
|   ├── config.py
|   └── file5.txt
|
├── file1.py
├── file2.csv
└── file3.txt

El built-inosmódulo tiene una serie de funciones útiles que se pueden utilizar para enumerar los contenidos del directorio y filtrar los resultados. Para obtener una lista de todos los archivos y carpetas en un directorio en particular en el sistema de archivos, useos.listdir()en versiones heredadas de Python oos.scandir()en Python 3.x.os.scandir()es el método preferido para usar si también desea obtener propiedades de archivos y directorios, como el tamaño del archivo y la fecha de modificación.

Lista de directorios en versiones heredadas de Python

En versiones anteriores a Python 3,os.listdir()es el método a utilizar para obtener un listado de directorios:

>>> import os
>>> entries = os.listdir('my_directory/')

os.listdir()devuelve una lista de Python que contiene los nombres de los archivos y subdirectorios en el directorio dado por el argumento path:

>>> os.listdir('my_directory/')
['sub_dir_c', 'file1.py', 'sub_dir_b', 'file3.txt', 'file2.csv', 'sub_dir']

Un listado de directorios como ese no es fácil de leer. Impresión de la salida de una llamada aos.listdir()El uso de un bucle ayuda a limpiar las cosas:

>>> entries = os.listdir('my_directory/')
>>> for entry in entries:
...     print(entry)
...
...
sub_dir_c
file1.py
sub_dir_b
file3.txt
file2.csv
sub_dir

Lista de directorios en versiones modernas de Python

En las versiones modernas de Python, una alternativa aos.listdir()es usaros.scandir()pathlib.Path().

os.scandir()se introdujo en Python 3.5 y está documentado en PEP 471.os.scandir()devuelve un iterador en lugar de una lista cuando se llama:

>>> import os
>>> entries = os.scandir('my_directory/')
>>> entries

LosScandirIteratorapunta a todas las entradas en el directorio actual. Puede hacer un bucle sobre el contenido del iterador e imprimir los nombres de archivo:

import os

with os.scandir('my_directory/') as entries:
    for entry in entries:
        print(entry.name)

Toma.os.scandir()Se utiliza en conjunción con elwithstatement porque soporta el protocolo del gestor de contexto. El uso de un gestor de contexto cierra el iterador y libera los recursos adquiridos automáticamente después de que el iterador se haya agotado. El resultado es una impresión de los nombres de archivo enmy_directory/tal como lo viste en elos.listdir()ejemplo:

sub_dir_c
file1.py
sub_dir_b
file3.txt
file2.csv
sub_dir

Otra forma de obtener un listado de directorios es usar elpathlibmódulo:

from pathlib import Path

entries = Path('my_directory/')
for entry in entries.iterdir():
    print(entry.name)

Los objetos devueltos porPathson tampocoPosixPathoWindowsPathLos objetos dependen del sistema operativo.

pathlib.Path()Los objetos tienen un.iterdir()método para crear un iterador de todos los archivos y carpetas de un directorio. Cada entrada aportada por.iterdir()contiene información sobre el archivo o directorio, como su nombre y atributos de archivo.pathlibse introdujo por primera vez en Python 3.4 y es una gran adición a Python que proporciona una interfaz orientada a objetos para el sistema de archivos.

En el ejemplo anterior, usted llamapathlib.Path()y pasarle un argumento de camino. El siguiente es el llamado a.iterdir()para obtener una lista de todos los archivos y directorios enmy_directory.

pathlibofrece un conjunto de clases que ofrecen la mayoría de las operaciones comunes en las rutas de una manera fácil y orientada a objetos. Usandopathlibes más eficiente, si no tan eficiente, como el uso de las funciones enos. Otro beneficio de usarpathliboveroses que reduce el número de importaciones que debe realizar para manipular las rutas del sistema de archivos. Para obtener más información, lea el módulo pathlib de Python 3: domar el sistema de archivos.

Ejecutar el código anterior produce lo siguiente:

sub_dir_c
file1.py
sub_dir_b
file3.txt
file2.csv
sub_dir

Usandopathlib.Path()oos.scandir()en lugar deos.listdir()es la forma preferida de obtener una lista de directorios, especialmente cuando se trabaja con código que necesita el tipo de archivo y la información de atributos de archivo.pathlib.Path()ofrece gran parte de la funcionalidad de manejo de archivos y rutas que se encuentra enosshutil, y sus métodos son más eficientes que algunos que se encuentran en estos módulos. Discutiremos cómo obtener propiedades de archivo en breve.

Aquí están de nuevo las funciones de lista de directorios:

Descripción de la función
os.listdir() Devuelve una lista de todos los archivos y carpetas de un directorio
os.scandir() Devuelve un iterador de todos los objetos de un directorio, incluida la información de atributos de archivo
pathlib.Path.iterdir() Devuelve un iterador de todos los objetos de un directorio, incluida la información de atributos de archivo

Estas funciones devuelven una lista de todo en el directorio, incluyendo subdirectorios. Puede que este no sea siempre el comportamiento que deseas. La siguiente sección le mostrará cómo filtrar los resultados de un listado de directorios.

Listar todos los archivos en un directorio

Esta sección le mostrará cómo imprimir los nombres de los archivos en un directorio usandoos.listdir(),os.scandir(), pathlib.Path(). Para filtrar directorios y solo listar archivos de un listado de directorios producido poros.listdir(), usoos.path:

import os

# List all files in a directory using os.listdir
basepath = 'my_directory/'
for entry in os.listdir(basepath):
    if os.path.isfile(os.path.join(basepath, entry)):
        print(entry)

Aquí, la llamada aos.listdir()devuelve una lista de todo en la ruta especificada, y luego esa lista es filtrada poros.path.isfile()para imprimir solo archivos y no directorios. Esto produce la siguiente salida:

file1.py
file3.txt
file2.csv

Una forma más fácil de listar archivos en un directorio es usaros.scandir()opathlib.Path():

import os

# List all files in a directory using scandir()
basepath = 'my_directory/'
with os.scandir(basepath) as entries:
    for entry in entries:
        if entry.is_file():
            print(entry.name)

Usandoos.scandir()tiene la ventaja de verse más limpio y ser más fácil de entender que usaros.listdir()Aunque es una línea de código más larga. Llamandoentry.is_file()en cada elemento de laScandirIteratorDevolucionesTrueSi el objeto es un archivo. La impresión de los nombres de todos los archivos en el directorio le da la siguiente salida:

file1.py
file3.txt
file2.csv

He aquí cómo listar archivos en un directorio usandopathlib.Path():

from pathlib import Path

basepath = Path('my_directory/')
files_in_basepath = basepath.iterdir()
for item in files_in_basepath:
    if item.is_file():
        print(item.name)

Toma, llama.is_file()En cada una de las entradas aportadas por.iterdir(). La salida producida es la misma:

file1.py
file3.txt
file2.csv

El código anterior se puede hacer más conciso si se combina elforEl bucle y elsiuna sola expresión generadora. Dan Bader tiene un excelente artículo sobre expresiones de generador y comprensión de listas.

La versión modificada se ve así:

from pathlib import Path

# List all files in directory using pathlib
basepath = Path('my_directory/')
files_in_basepath = (entry for entry in basepath.iterdir() if entry.is_file())
for item in files_in_basepath:
    print(item.name)

Esto produce exactamente la misma salida que el ejemplo anterior. Esta sección mostró que el filtrado de archivos o directorios utilizandoos.scandir()pathlib.Path()se siente más intuitivo y se ve más limpio que usandoos.listdir()En conjunción conos.path.

Subdirectorios de listado

Para listar subdirectorios en lugar de archivos, utilice uno de los métodos siguientes. Aquí es cómo usaros.listdir()os.path():

import os

# List all subdirectories using os.listdir
basepath = 'my_directory/'
for entry in os.listdir(basepath):
    if os.path.isdir(os.path.join(basepath, entry)):
        print(entry)

Manipular las rutas del sistema de archivos de esta manera puede volverse rápidamente engorroso cuando tiene varias llamadas aos.path.join(). Ejecutar esto en mi computadora produce la siguiente salida:

sub_dir_c
sub_dir_b
sub_dir

Aquí es cómo usaros.scandir():

import os

# List all subdirectories using scandir()
basepath = 'my_directory/'
with os.scandir(basepath) as entries:
    for entry in entries:
        if entry.is_dir():
            print(entry.name)

Como en el ejemplo del listado de archivos, aquí usted llama.is_dir()en cada entrada devuelta poros.scandir(). Si la entrada es un directorio,.is_dir()DevolucionesTrue, y el nombre del directorio está impreso. La salida es la misma que la anterior:

sub_dir_c
sub_dir_b
sub_dir

Aquí es cómo usarpathlib.Path():

from pathlib import Path

# List all subdirectory using pathlib
basepath = Path('my_directory/')
for entry in basepath.iterdir():
    if entry.is_dir():
        print(entry.name)

Llamando.is_dir()En cada entrada delbasepathiterator comprueba si una entrada es un archivo o un directorio. Si la entrada es un directorio, su nombre se imprime en la pantalla y la salida producida es la misma que la del ejemplo anterior:

sub_dir_c
sub_dir_b
sub_dir

Obtención de atributos de archivo

Python facilita la recuperación de atributos de archivo, como el tamaño del archivo y las veces modificadas. Esto se hace a través deos.stat(),os.scandir(), opathlib.Path().

os.scandir()pathlib.Path()recuperar un listado de directorios con atributos de archivo combinados. Esto puede ser potencialmente más eficiente que usaros.listdir()para listar archivos y luego obtener información de atributos de archivo para cada archivo.

Los ejemplos a continuación muestran cómo obtener el tiempo de los archivos enmy_directory/ltima modificación. La salida es en segundos:

>>> import os
>>> with os.scandir('my_directory/') as dir_contents:
...     for entry in dir_contents:
...         info = entry.stat()
...         print(info.st_mtime)
...
1539032199.0052035
1539032469.6324475
1538998552.2402923
1540233322.4009316
1537192240.0497339
1540266380.3434134

os.scandir()devuelve unScandirIteratorobjeto. Cada entrada en unScandirIteratorEl objeto tiene un.stat()método que recupera información sobre el archivo o directorio al que apunta..stat()proporciona información como el tamaño del archivo y la hora de la última modificación. En el ejemplo anterior, el código imprime elst_mtimeatributo, que es el momento en que se modificó por última vez el contenido del archivo.

Lospathlibmódulo tiene métodos correspondientes para recuperar información de archivo que dan los mismos resultados:

>>> from pathlib import Path
>>> current_dir = Path('my_directory')
>>> for path in current_dir.iterdir():
...     info = path.stat()
...     print(info.st_mtime)
...
1539032199.0052035
1539032469.6324475
1538998552.2402923
1540233322.4009316
1537192240.0497339
1540266380.3434134

En el ejemplo anterior, el código pasa por el objeto devuelto por.iterdir()y recupera atributos de archivo a través de un.stat()para cada archivo en la lista de directorios. Losst_mtimeatributo devuelve un valor flotante que representa segundos desde la época. Para convertir los valores devueltos porst_mtimecon fines de visualización, podría escribir una función de ayuda para convertir los segundos endatetimeobjeto:

from datetime import datetime
from os import scandir

def convert_date(timestamp):
    d = datetime.utcfromtimestamp(timestamp)
    formated_date = d.strftime('%d %b %Y')
    return formated_date

def get_files():
    dir_entries = scandir('my_directory/')
    for entry in dir_entries:
        if entry.is_file():
            info = entry.stat()
            print(f'{entry.name}t Last Modified: {convert_date(info.st_mtime)}')

Esto primero obtendrá una lista de archivos enmy_directoryy sus atributos y luego llamarconvert_date()para convertir la última vez que se modificó cada archivo en una forma legible por humanos.convert_date()hace uso de.strftime()para convertir el tiempo en segundos en una cadena.

Los argumentos pasaron a.strftime()son los siguientes:

  • %d: el día del mes
  • %b: el mes, en forma abreviada
  • %Y: el año

Juntas, estas directivas producen resultados que se ven así:

>>> get_files()
file1.py        Last modified:  04 Oct 2018
file3.txt       Last modified:  17 Sep 2018
file2.txt       Last modified:  17 Sep 2018

La sintaxis para convertir fechas y horas en cadenas puede ser bastante confusa. Para leer más al respecto, consulte la documentación oficial al respecto. Otra referencia útil que es fácil de recordar es http://strftime.org/.

Haciendo directorios

Tarde o temprano, los programas que escriba tendrán que crear directorios para almacenar datos en ellos.ospathlibIncluye funciones para crear directorios. Consideraremos estos:

Descripción de la función
os.mkdir() Crea un único subdirectorio
pathlib.Path.mkdir() Crea directorios individuales o múltiples
os.makedirs() Crea varios directorios, incluidos los directorios intermedios

Creación de un único directorio

Para crear un solo directorio, pase una ruta al directorio como un parámetro paraos.mkdir():

import os

os.mkdir('example_directory/')

Si ya existe un directorio,os.mkdir()elevaFileExistsError. Alternativamente, puede crear un directorio usandopathlib:

from pathlib import Path

p = Path('example_directory/')
p.mkdir()

Si el camino ya existe,mkdir()eleva aFileExistsError:

>>> p.mkdir()
Traceback (most recent call last):
  File '', line 1, in 
  File '/usr/lib/python3.5/pathlib.py', line 1214, in mkdir
    self._accessor.mkdir(self, mode)
  File '/usr/lib/python3.5/pathlib.py', line 371, in wrapped
    return strfunc(str(pathobj), *args)
FileExistsError: [Errno 17] File exists: '.'
[Errno 17] File exists: '.'

Para evitar errores como este, detecta el error cuando suceda y hazle saber a tu usuario:

from pathlib import Path

p = Path('example_directory')
try:
    p.mkdir()
except FileExistsError as exc:
    print(exc)

Alternativamente, puede ignorar elFileExistsErrorPasando elexist_ok=TrueArgumento a.mkdir():

from pathlib import Path

p = Path('example_directory')
p.mkdir(exist_ok=True)

Esto no generará un error si el directorio ya existe.

Creación de múltiples directorios

os.makedirs()Es similar aos.mkdir(). La diferencia entre los dos es que no sólo puedeos.makedirs()crear directorios individuales, también se puede utilizar para crear árboles de directorios. En otras palabras, puede crear cualquier carpeta intermedia necesaria para garantizar que exista una ruta completa.

os.makedirs()es similar a corrermkdir -pEn Bash. Por ejemplo, para crear un grupo de directorios como2018/10/05, todo lo que tienes que hacer es lo siguiente:

import os


os.makedirs('2018/10/05')

Esto creará una estructura de directorio anidada que contiene las carpetas 2018, 10 y 05:

.
|
└── 2018/
    └── 10/
        └── 05/

.makedirs()crea directorios con permisos predeterminados. Si necesita crear directorios con diferentes permisos llame.makedirs()y pase en el modo en que desea que se creen los directorios:

import os

os.makedirs('2018/10/05', mode=0o770)

Esto crea el2018/10/05estructura de directorios y otorga al propietario y al grupo de usuarios permisos de lectura, escritura y ejecución. El modo predeterminado es0o777, y los bits de permiso de archivo de los directorios principales existentes no se cambian. Para obtener más información sobre los permisos de archivo y cómo se aplica el modo, consulte los documentos.

Ejecutartreepara confirmar que se han aplicado los permisos adecuados:

$ tree -p -i .
.
[drwxrwx---]  2018
[drwxrwx---]  10
[drwxrwx---]  05

Esto imprime un árbol de directorios del directorio actual.treese utiliza normalmente para enumerar el contenido de los directorios en un formato de árbol. Pasando el-p-iArgumentos para imprimir los nombres de directorio y su información de permiso de archivo en una lista vertical.-pimprime los permisos de archivo, y-ihacetreeproducir una lista vertical sin líneas de sangría.

Como puede ver, todos los directorios tienen770Permisos. Una forma alternativa de crear directorios es usar.mkdir()Desdepathlib.Path:

import pathlib

p = pathlib.Path('2018/10/05')
p.mkdir(parents=True)

Pasandoparents=TrueaPath.mkdir()hace que se cree el directorio05y cualquier directorio padre necesario para hacer que la ruta sea válida.

Por defecto,os.makedirs()Path.mkdir()Levantar unOSErrorsi el directorio de destino ya existe. Este comportamiento puede ser anulado (a partir de Python 3.2)exist_ok=Truecomo un argumento de palabra clave cuando se llama a cada función.

Ejecutar el código anterior produce una estructura de directorio como la siguiente de una sola vez:

.
|
└── 2018/
    └── 10/
        └── 05/

Prefiero usarpathlibal crear directorios porque puedo usar la misma función para crear directorios únicos o anidados.

Nombre de archivo Pattern Matching

Después de obtener una lista de archivos en un directorio utilizando uno de los métodos anteriores, lo más probable es que desee buscar archivos que coincidan con un patrón en particular.

Estos son los métodos y funciones disponibles para usted:

  • endswith()startswith()métodos de string
  • fnmatch.fnmatch()
  • glob.glob()
  • pathlib.Path.glob()

Cada uno de estos se discute a continuación. Los ejemplos de esta sección se realizarán en un directorio llamadosome_directoryque tiene la siguiente estructura:

.
|
├── sub_dir/
|   ├── file1.py
|   └── file2.py
|
├── admin.py
├── data_01_backup.txt
├── data_01.txt
├── data_02_backup.txt
├── data_02.txt
├── data_03_backup.txt
├── data_03.txt
└── tests.py

Si sigues usando un shell de Bash, puedes crear la estructura de directorios anterior con los siguientes comandos:

$ mkdir some_directory
$ cd some_directory/
$ mkdir sub_dir
$ touch sub_dir/file1.py sub_dir/file2.py
$ touch data_{01..03}.txt data_{01..03}_backup.txt admin.py tests.py

Esto creará elsome_directory/directorio, cambiar en él, y luego crearsub_dir. La siguiente línea creafile1.pyfile2.pyensub_dir, y la última línea crea todos los demás archivos usando la expansión. Para obtener más información sobre la expansión de shell, visite este sitio.

Uso de métodos de string

Python tiene varios métodos incorporados para modificar y manipular cadenas. Dos de estos métodos,.startswith().endswith(), son útiles cuando está buscando patrones en nombres de archivo. Para hacer esto, primero obtenga un listado de directorios y luego repita sobre él:

>>> import os

>>> # Get .txt files
>>> for f_name in os.listdir('some_directory'):
...     if f_name.endswith('.txt'):
...         print(f_name)

El código anterior encuentra todos los archivos ensome_directory/, itera sobre ellos y utiliza.endswith()para imprimir los nombres de archivo que tienen el.txtExtensión de archivo. Ejecutar esto en mi computadora produce la siguiente salida:

data_01.txt
data_03.txt
data_03_backup.txt
data_02_backup.txt
data_02.txt
data_01_backup.txt

Simple coincidencia de patrones de nombre de archivo usandofnmatch

Los métodos de cadena están limitados en sus capacidades de coincidencia.fnmatchtiene funciones y métodos más avanzados para la coincidencia de patrones. Consideraremosfnmatch.fnmatch(), una función que admite el uso de comodines como*?para que coincida con los nombres de archivo. Por ejemplo, para encontrar todo.txtarchivos en un directorio usandofnmatch, harías lo siguiente:

>>> import os
>>> import fnmatch

>>> for file_name in os.listdir('some_directory/'):
...     if fnmatch.fnmatch(file_name, '*.txt'):
...         print(file_name)

Esto itera sobre la lista de archivos ensome_directoryy usos.fnmatch()para realizar una búsqueda comodín de archivos que tienen el.txtextensión.

Patrón más avanzado que empareja

Supongamos que quieres encontrar.txtarchivos que cumplan ciertos criterios. Por ejemplo, solo podría estar interesado en encontrar.txtarchivos que contienen la palabradata, un número entre un conjunto de subrayados, y la palabrabackupen su nombre de archivo. Algo similar adata_01_backup,data_02_backup, odata_03_backup.

Usandofnmatch.fnmatch()Puedes hacerlo de esta manera:

>>> for filename in os.listdir('.'):
...     if fnmatch.fnmatch(filename, 'data_*_backup.txt'):
...         print(filename)

Aquí, imprime solo los nombres de los archivos que coinciden con eldata_*_backup.txtpatrón. El asterisco en el patrón coincidirá con cualquier carácter, por lo que al ejecutarlo encontrará todos los archivos de texto cuyos nombres de archivo comiencen con la palabradatay terminan enbackup.txt, como se puede ver en la salida de abajo:

data_03_backup.txt
data_02_backup.txt
data_01_backup.txt

Nombre de archivo Pattern Matching Usingglob

Otro módulo útil para la coincidencia de patrones esglob.

.glob()en elglobEl módulo funciona comofnmatch.fnmatch()Pero a diferencia defnmatch.fnmatch(), trata archivos que comienzan con un punto (.) como especial.

UNIX y sistemas relacionados traducen patrones de nombres con comodines como?*en una lista de archivos. Esto se llama globbing.

Por ejemplo, escribirmv *.py python_files/en un shell UNIX se mueve (mv) todos los archivos con el.pyextensión desde el directorio actual al directoriopython_files. Los*es un comodín que significa «cualquier número de caracteres», y*.pyes el patrón glob. Esta capacidad de shell no está disponible en el sistema operativo Windows. Losglobmódulo añade esta capacidad en Python, lo que permite a los programas de Windows utilizar esta característica.

Aquí hay un ejemplo de cómo usarglobpara buscar todos los Python (.py) archivos de origen en el directorio actual:

>>> import glob
>>> glob.glob('*.py')
['admin.py', 'tests.py']

glob.glob('*.py')busca todos los archivos que tienen el.pyextensión en el directorio actual y los devuelve como una lista.globtambién admite comodines estilo shell para que coincidan con los patrones:

>>> import glob
>>> for name in glob.glob('*[0-9]*.txt'):
...     print(name)

Esto encuentra todo el texto (.txt) archivos que contienen dígitos en el nombre del archivo:

data_01.txt
data_03.txt
data_03_backup.txt
data_02_backup.txt
data_02.txt
data_01_backup.txt

globhace que sea fácil buscar archivos recursivamente en subdirectorios también:

>>> import glob
>>> for file in glob.iglob('**/*.py', recursive=True):
...     print(file)

Este ejemplo hace uso deglob.iglob()para buscar.pyarchivos en el directorio y subdirectorios actuales. Pasandorecursive=TrueComo argumento para.iglob()hace que la búsqueda de.pyarchivos en el directorio actual y en cualquier subdirectorio. La diferencia entreglob.iglob()glob.glob()¿Qué es eso?.iglob()devuelve un iterador en lugar de una lista.

Ejecutar el programa anterior produce lo siguiente:

admin.py
tests.py
sub_dir/file1.py
sub_dir/file2.py

pathlibcontiene métodos similares para hacer listas de archivos flexibles. El siguiente ejemplo muestra cómo puede usar.Path.glob()para listar los tipos de archivo que comienzan con la letrap:

>>> from pathlib import Path
>>> p = Path('.')
>>> for name in p.glob('*.p*'):
...     print(name)

admin.py
scraper.py
docs.pdf

Llamandop.glob('*.p*')devuelve un objeto generador que apunta a todos los archivos del directorio actual que comienzan con la letrapen su extensión de archivo.

Path.glob()Es similar aos.glob()discutido anteriormente. Como puedes ver,pathlibcombina muchas de las mejores características de laos,os.path, globmódulos en un solo módulo, lo que lo convierte en un placer de usar.

Para recapitular, aquí hay una tabla de las funciones que hemos cubierto en esta sección:

Descripción de la función
startswith() Prueba si una cadena comienza con un patrón especificado y devuelveTrueoFalse
endswith() Prueba si una cadena termina con un patrón especificado y devuelveTrueoFalse
fnmatch.fnmatch(filename, pattern) Prueba si el nombre de archivo coincide con el patrón y devuelveTrueoFalse
glob.glob() Devuelve una lista de nombres de archivo que coinciden con un patrón
pathlib.Path.glob() Encuentra patrones en los nombres de ruta y devuelve un objeto generador

Travesía de directorios y procesamiento de archivos

Una tarea de programación común es recorrer un árbol de directorios y procesar archivos en el árbol. Vamos a explorar cómo funciona la función incorporada de Pythonos.walk()Se puede utilizar para hacer esto.os.walk()se usa para generar un nombre de archivo en un árbol de directorios caminando por el árbol de arriba hacia abajo o de abajo hacia arriba. Para los propósitos de esta sección, estaremos manipulando el siguiente árbol de directorios:

.
|
├── folder_1/
|   ├── file1.py
|   ├── file2.py
|   └── file3.py
|
├── folder_2/
|   ├── file4.py
|   ├── file5.py
|   └── file6.py
|
├── test1.txt
└── test2.txt

El siguiente es un ejemplo que muestra cómo listar todos los archivos y directorios en un árbol de directorios usandoos.walk().

os.walk()por defecto para atravesar directorios de una manera de arriba hacia abajo:

# Walking a directory tree and printing the names of the directories and files
for dirpath, dirnames, files in os.walk('.'):
    print(f'Found directory: {dirpath}')
    for file_name in files:
        print(file_name)

os.walk()devuelve tres valores en cada iteración del bucle:

  1. El nombre de la carpeta actual

  2. Una lista de carpetas en la carpeta actual

  3. Una lista de archivos en la carpeta actual

En cada iteración, imprime los nombres de los subdirectorios y archivos que encuentra:

Found directory: .
test1.txt
test2.txt
Found directory: ./folder_1
file1.py
file3.py
file2.py
Found directory: ./folder_2
file4.py
file5.py
file6.py

Para atravesar el árbol de directorios de una manera ascendente, pase untopdown=Falsekeyword Argumentoos.walk():

for dirpath, dirnames, files in os.walk('.', topdown=False):
    print(f'Found directory: {dirpath}')
    for file_name in files:
        print(file_name)

Pasando eltopdown=FalseEl argumento haráos.walk()imprime primero los archivos que encuentra en los subdirectorios:

Found directory: ./folder_1
file1.py
file3.py
file2.py
Found directory: ./folder_2
file4.py
file5.py
file6.py
Found directory: .
test1.txt
test2.txt

Como puede ver, el programa comenzó enumerando el contenido de los subdirectorios antes de enumerar el contenido del directorio raíz. Esto es muy útil en situaciones en las que desea eliminar recursivamente archivos y directorios. Usted aprenderá cómo hacer esto en las secciones de abajo. Por defecto,os.walkno entra en enlaces simbólicos que se resuelven en directorios. Este comportamiento puede ser anulado llamándolo con unfollowlinks=Trueargumento.

Creación de archivos y directorios temporales

Python proporciona un módulo útil para crear archivos temporales y directorios llamadostempfile.

tempfilese puede usar para abrir y almacenar datos temporalmente en un archivo o directorio mientras se ejecuta el programa.tempfilese encarga de la eliminación de los archivos temporales cuando el programa se hace con ellos.

A continuación se explica cómo crear un archivo temporal:

from tempfile import TemporaryFile

# Create a temporary file and write some data to it
fp = TemporaryFile('w+t')
fp.write('Hello universe!')

# Go back to the beginning and read data from file
fp.seek(0)
data = fp.read()

# Close the file, after which it will be removed
fp.close()

El primer paso es importarTemporaryFileDesde el punto de vistatempfilemódulo. A continuación, cree un archivo como objeto usando elTemporaryFile()método llamándolo y pasando el modo en el que desea abrir el archivo. Esto creará y abrirá un archivo que se puede utilizar como un área de almacenamiento temporal.

En el ejemplo anterior, el modo es'w+t', lo que hacetempfilecrear un archivo de texto temporal en modo de escritura. No hay necesidad de dar al archivo temporal un nombre de archivo, ya que se destruirá después de que el script haya terminado de ejecutarse.

Después de escribir en el archivo, puede leerlo y cerrarlo cuando haya terminado de procesarlo. Una vez que se cierra el archivo, se eliminará del sistema de archivos. Si necesita nombrar los archivos temporales producidos usandotempfile, usotempfile.NamedTemporaryFile().

Los archivos temporales y directorios creados usandotempfilese almacenan en un directorio especial del sistema para almacenar archivos temporales. Python busca una lista estándar de directorios para encontrar uno en el que el usuario pueda crear archivos.

En Windows, los directorios sonC:TEMP,C:TMP,TEMP, TMPEn ese orden. En todas las demás plataformas, los directorios son/tmp,/var/tmp, /usr/tmpEn ese orden. Como último recurso,tempfileguardará archivos y directorios temporales en el directorio actual.

.TemporaryFile()es también un gestor de contexto por lo que se puede utilizar junto con elwithdeclaración. El uso de un administrador de contexto se encarga de cerrar y eliminar el archivo automáticamente después de que se haya leído:

with TemporaryFile('w+t') as fp:
    fp.write('Hello universe!')
    fp.seek(0)
    fp.read()
# File is now closed and removed

Esto crea un archivo temporal y lee datos de él. Tan pronto como se lee el contenido del archivo, el archivo temporal se cierra y se elimina del sistema de archivos.

tempfileTambién se puede utilizar para crear directorios temporales. Veamos cómo puedes hacer esto usandotempfile.TemporaryDirectory():

>>> import tempfile
>>> with tempfile.TemporaryDirectory() as tmpdir:
...     print('Created temporary directory ', tmpdir)
...     os.path.exists(tmpdir)
...
Created temporary directory  /tmp/tmpoxbkrm6c
True

>>> # Directory contents have been removed
...
>>> tmpdir
'/tmp/tmpoxbkrm6c'
>>> os.path.exists(tmpdir)
False

Llamandotempfile.TemporaryDirectory()crea un directorio temporal en el sistema de archivos y devuelve un objeto que representa este directorio. En el ejemplo anterior, el directorio se crea usando un gestor de contexto, y el nombre del directorio se almacena entmpdir. La tercera línea imprime el nombre del directorio temporal, yos.path.exists(tmpdir)confirma si el directorio se creó realmente en el sistema de archivos.

Después de que el gestor de contexto se sale de contexto, el directorio temporal se elimina y una llamada aos.path.exists(tmpdir)DevolucionesFalse, lo que significa que el directorio se eliminó con éxito.

Eliminación de archivos y directorios

Puede eliminar archivos individuales, directorios y árboles de directorios completos utilizando los métodos que se encuentran en elos,shutil, pathlibmódulos. En las siguientes secciones se describe cómo eliminar archivos y directorios que ya no necesita.

Eliminar archivos en Python

Para eliminar un solo archivo, usepathlib.Path.unlink(),os.remove(). oos.unlink().

os.remove()os.unlink()son semánticamente idénticos. Para eliminar un archivo usandoos.remove(), haga lo siguiente:

import os

data_file = 'C:\Users\vuyisile\Desktop\Test\data.txt'
os.remove(data_file)

Eliminar un archivo usandoos.unlink()es similar a cómo lo haces usandoos.remove():

import os

data_file = 'C:\Users\vuyisile\Desktop\Test\data.txt'
os.unlink(data_file)

Llamando.unlink()o.remove()en un archivo elimina el archivo del sistema de archivos. Estas dos funciones producirán unOSErrorsi la ruta de acceso que se les ha pasado apunta a un directorio en lugar de a un archivo. Para evitar esto, puede verificar que lo que está tratando de eliminar es en realidad un archivo y solo eliminarlo si lo es, o puede usar el manejo de excepciones para manejar el archivo.OSError:

import os

data_file = 'home/data.txt'

# If the file exists, delete it
if os.path.isfile(data_file):
    os.remove(data_file)
else:
    print(f'Error: {data_file} not a valid filename')

os.path.isfile()comprueba sidata_fileEn realidad es un archivo. Si es así, se elimina por la llamada aos.remove(). Sidata_fileapunta a una carpeta, se imprime un mensaje de error en la consola.

En el siguiente ejemplo se muestra cómo usar el manejo de excepciones para manejar errores al eliminar archivos:

import os

data_file = 'home/data.txt'

# Use exception handling
try:
    os.remove(data_file)
except OSError as e:
    print(f'Error: {data_file} : {e.strerror}')

El código anterior intenta eliminar el archivo primero antes de verificar su tipo. Sidata_fileEn realidad no es un archivo, elOSErrorque se lanza se maneja en elexcepty se imprime un mensaje de error en la consola. El mensaje de error que se imprime se formatea con f-strings de Python.

Por último, también se puede utilizarpathlib.Path.unlink()para eliminar archivos:

from pathlib import Path

data_file = Path('home/data.txt')

try:
    data_file.unlink()
except IsADirectoryError as e:
    print(f'Error: {data_file} : {e.strerror}')

Esto crea unPathobjeto llamadodata_fileEsto apunta a un archivo. Llamando.remove()ondata_fileborraráhome/data.txt. Sidata_fileapunta a un directorio, unIsADirectoryErrorEstá elevado. Vale la pena señalar que el programa Python anterior tiene los mismos permisos que el usuario que lo ejecuta. Si el usuario no tiene permiso para eliminar el archivo, unPermissionErrorEstá elevado.

Borrar directorios

La biblioteca estándar ofrece las siguientes funciones para eliminar directorios:

  • os.rmdir()
  • pathlib.Path.rmdir()
  • shutil.rmtree()

Para eliminar un único directorio o carpeta, utiliceos.rmdir()opathlib.rmdir(). Estas dos funciones solo funcionan si el directorio que intenta eliminar está vacío. Si el directorio no está vacío, unOSErrorEstá elevado. Aquí es cómo eliminar una carpeta:

import os

trash_dir = 'my_documents/bad_dir'

try:
    os.rmdir(trash_dir)
except OSError as e:
    print(f'Error: {trash_dir} : {e.strerror}')

Aquí, eltrash_dirdirectorio se elimina pasando su ruta aos.rmdir(). Si el directorio no está vacío, se imprime un mensaje de error en la pantalla:

Traceback (most recent call last):
  File '', line 1, in 
OSError: [Errno 39] Directory not empty: 'my_documents/bad_dir'

Alternativamente, puede utilizarpathlibPara eliminar directorios:

from pathlib import Path

trash_dir = Path('my_documents/bad_dir')

try:
    trash_dir.rmdir()
except OSError as e:
    print(f'Error: {trash_dir} : {e.strerror}')

Aquí, usted crea unPathobjeto que apunta al directorio que se va a eliminar. Llamando.rmdir()en elPathobject lo eliminará si está vacío.

Eliminar árboles de directorios completos

Para eliminar directorios no vacíos y árboles de directorios completos, Python ofreceshutil.rmtree():

import shutil

trash_dir = 'my_documents/bad_dir'

try:
    shutil.rmtree(trash_dir)
except OSError as e:
    print(f'Error: {trash_dir} : {e.strerror}')

Todo entrash_dirSe elimina cuandoshutil.rmtree()Se llama a ello. Puede haber casos en los que desee eliminar carpetas vacías de forma recursiva. Puede hacer esto usando uno de los métodos discutidos anteriormente junto conos.walk():

import os

for dirpath, dirnames, files in os.walk('.', topdown=False):
    try:
        os.rmdir(dirpath)
    except OSError as ex:
        pass

Esto recorre el árbol de directorios e intenta eliminar cada directorio que encuentra. Si el directorio no está vacío, unOSErrorse levanta y ese directorio se omite. La siguiente tabla enumera las funciones cubiertas en esta sección:

Descripción de la función
os.remove() Elimina un archivo y no elimina directorios
os.unlink() Es idéntico aos.remove()y elimina un solo archivo
pathlib.Path.unlink() Elimina un archivo y no puede eliminar directorios
os.rmdir() Elimina un directorio vacío
pathlib.Path.rmdir() Elimina un directorio vacío
shutil.rmtree() Elimina todo el árbol de directorios y se puede utilizar para eliminar directorios no vacíos

Copiar, mover y renombrar archivos y directorios

Python se embarca con elshutilmódulo.shutiles la abreviatura de shell utilities. Proporciona una serie de operaciones de alto nivel en archivos para admitir la copia, el archivo y la eliminación de archivos y directorios. En esta sección, aprenderá cómo mover y copiar archivos y directorios.

Copiar archivos en Python

shutilofrece un par de funciones para copiar archivos. Las funciones más utilizadas sonshutil.copy()shutil.copy2(). Para copiar un archivo de una ubicación a otra usandoshutil.copy(), haga lo siguiente:

import shutil

src = 'path/to/file.txt'
dst = 'path/to/dest_dir'
shutil.copy(src, dst)

shutil.copy()es comparable a lacpen sistemas basados en UNIX.shutil.copy(src, dst)copiará el archivosrca la ubicación especificada endst. Sidstes un archivo, el contenido de ese archivo se reemplaza con el contenido desrc. Sidstes un directorio, entoncessrcse copiará en ese directorio.shutil.copy()solo copia el contenido del archivo y los permisos del archivo. Otros metadatos como los tiempos de creación y modificación del archivo no se conservan.

Para conservar todos los metadatos del archivo al copiar, utiliceshutil.copy2():

import shutil

src = 'path/to/file.txt'
dst = 'path/to/dest_dir'
shutil.copy2(src, dst)

Usando.copy2()conserva detalles sobre el archivo, como el último tiempo de acceso, los bits de permiso, el último tiempo de modificación y los indicadores.

Copiar directorios

Mientrasshutil.copy()solo copia un único archivo,shutil.copytree()copiará un directorio completo y todo lo que contiene.shutil.copytree(src, dest)toma dos argumentos: un directorio de origen y el directorio de destino donde se copiarán los archivos y carpetas.

Aquí hay un ejemplo de cómo copiar el contenido de una carpeta a una ubicación diferente:

>>> import shutil
>>> shutil.copytree('data_1', 'data1_backup')
'data1_backup'

En este ejemplo,.copytree()Copiar el contenido dedata_1a una nueva ubicacióndata1_backupy devuelve el directorio de destino. El directorio de destino no debe existir ya. Se creará, así como directorios de padres que faltan.shutil.copytree()es una buena manera de hacer una copia de seguridad de sus archivos.

Mover archivos y directorios

Para mover un archivo o directorio a otra ubicación, useshutil.move(src, dst).

srces el archivo o directorio que se va a mover ydstes el destino:

>>> import shutil
>>> shutil.move('dir_1/', 'backup/')
'backup'

shutil.move('dir_1/', 'backup/')se muevedir_1/enbackup/sibackup/existe. Sibackup/No existe,dir_1/Será rebautizado comobackup.

Cambiar el nombre de los archivos y directorios

Python incluyeos.rename(src, dst)para renombrar archivos y directorios:

>>> os.rename('first.zip', 'first_01.zip')

La línea de arriba cambiará de nombrefirst.zipafirst_01.zip. Si la ruta de destino apunta a un directorio, generará unOSError.

Otra forma de renombrar archivos o directorios es usarrename()Desde el punto de vistapathlibmódulo:

>>> from pathlib import Path
>>> data_file = Path('data_01.txt')
>>> data_file.rename('data.txt')

Para cambiar el nombre de los archivos usandopathlibPrimero se crea unpathlib.Path()objeto que contiene una ruta de acceso al archivo que desea reemplazar. El siguiente paso es llamarrename()en el objeto ruta y pase un nuevo nombre de archivo para el archivo o directorio que va a renombrar.

Archivado

Los archivos son una manera conveniente de empaquetar varios archivos en uno. Los dos tipos de archivo más comunes son ZIP y TAR. Los programas de Python que escribes pueden crear, leer y extraer datos de archivos. Aprenderá a leer y escribir en ambos formatos de archivo en esta sección.

Lectura de archivos ZIP

Loszipfilemodule es un módulo de bajo nivel que forma parte de la biblioteca estándar de Python.zipfiletiene funciones que facilitan la apertura y extracción de archivos ZIP. Para leer el contenido de un archivo ZIP, lo primero que hay que hacer es crear unZipFileobjeto.ZipFileLos objetos son similares a los objetos de archivo creados usandoopen().ZipFilees también un gestor de contexto y por lo tanto apoya lawithdeclaración:

import zipfile

with zipfile.ZipFile('data.zip', 'r') as zipobj:

Aquí, usted crea unZipFileEl nombre del archivo ZIP para abrir en modo de lectura. Después de abrir un archivo ZIP, se puede acceder a la información sobre el archivo a través de las funciones proporcionadas por elzipfilemódulo. Losdata.zipEl archivo en el ejemplo anterior se creó a partir de un directorio llamadodataque contiene un total de 5 archivos y 1 subdirectorio:

.
|
├── sub_dir/
|   ├── bar.py
|   └── foo.py
|
├── file1.py
├── file2.py
└── file3.py

Para obtener una lista de archivos en el archivo, llamenamelist()en elZipFileobjeto:

import zipfile

with zipfile.ZipFile('data.zip', 'r') as zipobj:
    zipobj.namelist()

Esto produce una lista:

['file1.py', 'file2.py', 'file3.py', 'sub_dir/', 'sub_dir/bar.py', 'sub_dir/foo.py']

.namelist()devuelve una lista de nombres de los archivos y directorios del archivo. Para recuperar información sobre los archivos en el archivo, utilice.getinfo():

import zipfile

with zipfile.ZipFile('data.zip', 'r') as zipobj:
    bar_info = zipobj.getinfo('sub_dir/bar.py')
    bar_info.file_size

Aquí está la salida:

15277

.getinfo()devuelve unZipInfoObjeto que almacena información sobre un solo miembro del archivo. Para obtener información sobre un archivo en el archivo, pase su ruta como un argumento a.getinfo(). Usandogetinfo(), puede recuperar información sobre los miembros del archivo, como la fecha en que se modificaron por última vez los archivos, sus tamaños comprimidos y sus nombres de archivo completos. Acceso.file_sizerecupera el tamaño original del archivo en bytes.

En el siguiente ejemplo se muestra cómo recuperar más detalles sobre los archivos archivados en un REPL de Python. Asumir que elzipfileEl módulo ha sido importado ybar_infoes el mismo objeto que creaste en ejemplos anteriores:

>>> bar_info.date_time
(2018, 10, 7, 23, 30, 10)
>>> bar_info.compress_size
2856
>>> bar_info.filename
'sub_dir/bar.py'

bar_infoContiene detalles sobrebar.pycomo su tamaño cuando se comprime y su trayectoria completa.

La primera línea muestra cómo recuperar la última fecha modificada de un archivo. La siguiente línea muestra cómo obtener el tamaño del archivo después de la compresión. La última línea muestra el camino completo debar.pyen el archivo.

ZipFileadmite el protocolo de administrador de contexto, por lo que puede usarlo con elwithdeclaración. Al hacer esto, se cierra automáticamente elZipFileobjeto después de que haya terminado con él. Intentar abrir o extraer archivos de un archivo cerradoZipFileEl objeto dará lugar a un error.

Extracción de archivos ZIP

Loszipfilemódulo le permite extraer uno o más archivos de archivos ZIP a través de.extract().extractall().

Estos métodos extraen archivos al directorio actual de forma predeterminada. Ambos tienen una opciónpathparámetro que le permite especificar un directorio diferente para extraer archivos. Si el directorio no existe, se crea automáticamente. Para extraer archivos del archivo, haga lo siguiente:

>>> import zipfile
>>> import os

>>> os.listdir('.')
['data.zip']

>>> data_zip = zipfile.ZipFile('data.zip', 'r')

>>> # Extract a single file to current directory
>>> data_zip.extract('file1.py')
'/home/terra/test/dir1/zip_extract/file1.py'

>>> os.listdir('.')
['file1.py', 'data.zip']

>>> # Extract all files into a different directory
>>> data_zip.extractall(path='extract_dir/')

>>> os.listdir('.')
['file1.py', 'extract_dir', 'data.zip']

>>> os.listdir('extract_dir')
['file1.py', 'file3.py', 'file2.py', 'sub_dir']

>>> data_zip.close()

La tercera línea de código es una llamada aos.listdir(), que muestra que el directorio actual solo tiene un archivo,data.zip.

A continuación, abresdata.zipen modo de lectura y llamada.extract()para extraerfile1.pyDe él..extract()devuelve la ruta completa del archivo extraído. Puesto que no hay un camino especificado,.extract()extractosfile1.pyhacia el directorio actual.

La siguiente línea imprime un listado de directorios que muestra que el directorio actual ahora incluye el archivo extraído además del archivo original. La línea siguiente muestra cómo extraer todo el archivo en elzip_extractdirectorio..extractall()Crea elextract_diry extrae el contenido dedata.zipEn él. La última línea cierra el archivo ZIP.

Extracción de datos de archivos protegidos por contraseña

zipfileadmite la extracción de ZIP protegidos por contraseña. Para extraer archivos ZIP protegidos por contraseña, pase la contraseña a la.extract()o.extractall()Método como argumento:

>>> import zipfile

>>> with zipfile.ZipFile('secret.zip', 'r') as pwd_zip:
...     # Extract from a password protected archive
...     pwd_zip.extractall(path='extract_dir', pwd='[email protected]')

Esto abre elsecret.zipArchivo en modo de lectura. Se proporciona una contraseña para.extractall(), y el contenido del archivo se extraen aextract_dir. El archivo se cierra automáticamente después de la extracción se ha completado gracias a lawithdeclaración.

Creación de nuevos archivos ZIP

Para crear un nuevo archivo ZIP, abra unZipFileobjeto en modo de escritura (w) y agregue los archivos que desea archivar:

>>> import zipfile

>>> file_list = ['file1.py', 'sub_dir/', 'sub_dir/bar.py', 'sub_dir/foo.py']
>>> with zipfile.ZipFile('new.zip', 'w') as new_zip:
...     for name in file_list:
...         new_zip.write(name)

En el ejemplo,new_zipse abre en modo de escritura y cada archivo enfile_listse añade al archivo. Cuando elwithsuite de declaración ha terminado,new_zipestá cerrado. Abrir un archivo ZIP en el modo de escritura borra el contenido del archivo y crea un nuevo archivo.

Para agregar archivos a un archivo existente, abra unZipFileobjeto en modo anexo y, a continuación, agregue los archivos:

>>> # Open a ZipFile object in append mode
>>> with zipfile.ZipFile('new.zip', 'a') as new_zip:
...     new_zip.write('data.txt')
...     new_zip.write('latin.txt')

Toma, abres elnew.ziparchive creado en el ejemplo anterior en modo append. Apertura de laZipFileobjeto en modo anexo le permite agregar nuevos archivos al archivo ZIP sin eliminar su contenido actual. Después de agregar archivos al archivo ZIP, elwithstatement sale de contexto y cierra el archivo ZIP.

Apertura Archivos TAR

Los archivos TAR son archivos de archivo sin comprimir como ZIP. Se pueden comprimir utilizando los métodos de compresión gzip, bzip2 e lzma. LosTarFilepermite la lectura y escritura de archivos TAR.

Haz esto para leerlo de un archivo:

import tarfile

with tarfile.open('example.tar', 'r') as tar_file:
    print(tar_file.getnames())

tarfileLos objetos se abren como la mayoría de los objetos similares a archivos. Tienen unopen()función que toma un modo que determina cómo se va a abrir el archivo.

Utilice el'r','w'o'a'modos para abrir un archivo TAR sin comprimir para leer, escribir y anexar, respectivamente. Para abrir archivos TAR comprimidos, pase un argumento de modo atarfile.open()Esto es en la formafilemode[:compression]. La siguiente tabla enumera los posibles modos en los que se pueden abrir los archivos TAR:

ModeAction
r Abre el archivo para la lectura con compresión transparente
r:gz Abre el archivo para la lectura con compresión gzip
r:bz2 Abre el archivo para la lectura con la compresión bzip2
r:xz Abre el archivo para la lectura con compresión lzma
w Abre el archivo para la escritura sin comprimir
w:gz Abre el archivo para la escritura comprimida gzip
w:xz Abre el archivo para la escritura comprimida de lzma
a Abre el archivo para agregar sin compresión

.open()por defecto a'r'modo. Para leer un archivo TAR sin comprimir y recuperar los nombres de los archivos en él, use.getnames():

>>> import tarfile

>>> tar = tarfile.open('example.tar', mode='r')
>>> tar.getnames()
['CONTRIBUTING.rst', 'README.md', 'app.py']

Esto devuelve una lista con los nombres del contenido del archivo.

Nota: Con el propósito de mostrarle cómo usar diferentestarfilemétodos de objeto, el archivo TAR en los ejemplos se abre y se cierra manualmente en una sesión REPL interactiva.

Interactuar con el archivo TAR de esta manera le permite ver la salida de ejecutar cada comando. Normalmente, querría usar un administrador de contexto para abrir objetos similares a archivos.

Se puede acceder a los metadatos de cada entrada en el archivo utilizando atributos especiales:

>>> for entry in tar.getmembers():
...     print(entry.name)
...     print(' Modified:', time.ctime(entry.mtime))
...     print(' Size    :', entry.size, 'bytes')
...     print()
CONTRIBUTING.rst
 Modified: Sat Nov  1 09:09:51 2018
 Size    : 402 bytes

README.md
 Modified: Sat Nov  3 07:29:40 2018
 Size    : 5426 bytes

app.py
 Modified: Sat Nov  3 07:29:13 2018
 Size    : 6218 bytes

En este ejemplo, se realiza un bucle a través de la lista de archivos devueltos por.getmembers()e imprimir los atributos de cada archivo. Los objetos devueltos por.getmembers()tienen atributos a los que se puede acceder mediante programación, como el nombre, el tamaño y la última hora modificada de cada uno de los archivos del archivo. Después de leer o escribir en el archivo, debe cerrarse para liberar recursos del sistema.

Extracción de archivos de un archivo TAR

En esta sección, aprenderá cómo extraer archivos de archivos TAR utilizando los siguientes métodos:

  • .extract()
  • .extractfile()
  • .extractall()

Para extraer un solo archivo de un archivo TAR, utiliceextract(), pasando por el nombre de archivo:

>>> tar.extract('README.md')
>>> os.listdir('.')
['README.md', 'example.tar']

LosREADME.mdEl archivo se extrae del archivo al sistema de archivos. Llamandoos.listdir()confirma queREADME.mdEl archivo fue extraído con éxito en el directorio actual. Para desempaquetar o extraer todo del archivo, use.extractall():

>>> tar.extractall(path="extracted/")

.extractall()Tiene un opcionalpathArgumento para especificar dónde deben ir los archivos extraídos. Aquí, el archivo se desempaqueta en elextracteddirectorio. Los siguientes comandos muestran que el archivo se extrajo correctamente:

$ ls
example.tar  extracted  README.md

$ tree
.
├── example.tar
├── extracted
|   ├── app.py
|   ├── CONTRIBUTING.rst
|   └── README.md
└── README.md

1 directory, 5 files

$ ls extracted/
app.py  CONTRIBUTING.rst  README.md

Para extraer un objeto de archivo para leerlo o escribirlo, utilice.extractfile(), que toma un nombre de archivo oTarInfoobjeto a extraer como argumento..extractfile()devuelve un objeto similar a un archivo que se puede leer y usar:

>>> f = tar.extractfile('app.py')
>>> f.read()
>>> tar.close()

Los archivos abiertos siempre deben cerrarse después de haber sido leídos o escritos. Para cerrar un archivo, llame.close()en el archivo de archivo manejar o utilizar elwithdeclaración al creartarfileobjetos para cerrar automáticamente el archivo cuando haya terminado. Esto libera los recursos del sistema y escribe cualquier cambio que haya realizado en el archivo en el sistema de archivos.

Creación de nuevos archivos TAR

Así es como lo haces:

>>> import tarfile

>>> file_list = ['app.py', 'config.py', 'CONTRIBUTORS.md', 'tests.py']
>>> with tarfile.open('packages.tar', mode='w') as tar:
...     for file in file_list:
...         tar.add(file)

>>> # Read the contents of the newly created archive
>>> with tarfile.open('package.tar', mode='r') as t:
...     for member in t.getmembers():
...         print(member.name)
app.py
config.py
CONTRIBUTORS.md
tests.py

Primero, haga una lista de archivos que se agregarán al archivo para que no tenga que agregar cada archivo manualmente.

La siguiente línea utiliza elwithadministrador de contexto para abrir un nuevo archivo llamadopackages.taren el modo de escritura. Abrir un archivo en el modo de escritura ('w') le permite escribir nuevos archivos en el archivo. Todos los archivos existentes en el archivo se eliminan y se crea un nuevo archivo.

Después de que el archivo es creado y poblado, elwithEl administrador de contextos lo cierra automáticamente y lo guarda en el sistema de archivos. Las últimas tres líneas abren el archivo que acabas de crear e imprimen los nombres de los archivos que contiene.

Para agregar nuevos archivos a un archivo existente, abra el archivo en modo anexo ('a'):

>>> with tarfile.open('package.tar', mode='a') as tar:
...     tar.add('foo.bar')

>>> with tarfile.open('package.tar', mode='r') as tar:
...     for member in tar.getmembers():
...         print(member.name)
app.py
config.py
CONTRIBUTORS.md
tests.py
foo.bar

Abrir un archivo en modo anexo le permite agregar nuevos archivos sin eliminar los que ya están en él.

Trabajar con archivos comprimidos

tarfileTambién puede leer y escribir archivos TAR comprimidos usando compresión gzip, bzip2 e lzma. Para leer o escribir en un archivo comprimido, usetarfile.open(), pasando en el modo apropiado para el tipo de compresión.

Por ejemplo, para leer o escribir datos en un archivo TAR comprimido usando gzip, use el comando'r:gz'o'w:gz'modos respectivamente:

>>> files = ['app.py', 'config.py', 'tests.py']
>>> with tarfile.open('packages.tar.gz', mode='w:gz') as tar:
...     tar.add('app.py')
...     tar.add('config.py')
...     tar.add('tests.py')

>>> with tarfile.open('packages.tar.gz', mode='r:gz') as t:
...     for member in t.getmembers():
...         print(member.name)
app.py
config.py
tests.py

Los'w:gz'el modo abre el archivo para la escritura comprimida gzip y'r:gz'abre el archivo para la lectura comprimida de gzip. No es posible abrir archivos comprimidos en modo anexo. Para agregar archivos a un archivo comprimido, debe crear un nuevo archivo.

Una forma más fácil de crear archivos

La biblioteca estándar de Python también admite la creación de archivos TAR y ZIP utilizando los métodos de alto nivel en elshutilmódulo. Las utilidades de archivo enshutille permite crear, leer y extraer archivos ZIP y TAR. Estas utilidades dependen del nivel inferiortarfilezipfilemódulos.

Trabajar con archivos usandoshutil.make_archive()

shutil.make_archive()toma al menos dos argumentos: el nombre del archivo y un formato de archivo.

De forma predeterminada, comprime todos los archivos del directorio actual en el formato de archivo especificado en elformatargumento. Usted puede pasar en un opcionalroot_dirpara comprimir archivos en un directorio diferente..make_archive()apoya elzip,tar,bztar, gztarformatos de archivo.

Así es como crear un archivo TAR usandoshutil:

import shutil

# shutil.make_archive(base_name, format, root_dir)
shutil.make_archive('data/backup', 'tar', 'data/')

Esto copia todo endata/y crea un archivo llamadobackup.taren el sistema de archivos y devuelve su nombre. Para extraer el archivo, llame.unpack_archive():

shutil.unpack_archive('backup.tar', 'extract_dir/')

Llamando.unpack_archive()y pasando en un nombre de archivo y directorio de destino extrae el contenido debackup.tarenextract_dir/. Los archivos ZIP se pueden crear y extraer de la misma manera.

Lectura de varios archivos

Python admite la lectura de datos de múltiples flujos de entrada o de una lista de archivos a través de lafileinputmódulo. Este módulo le permite hacer un bucle sobre el contenido de uno o más archivos de texto de forma rápida y sencilla. Esta es la forma típicafileinputse utiliza:

import fileinput
for line in fileinput.input()
    process(line)

fileinputobtiene su entrada de argumentos de línea de comandos pasados asys.argvpor defecto.

Usandofileinputpara hacer un bucle sobre múltiples archivos

Vamos a usarfileinputpara construir una versión cruda de la utilidad UNIX comúncat. Loscatutilidad lee archivos secuencialmente, escribiéndolos a la salida estándar. Cuando se le da más de un archivo en sus argumentos de línea de comandos,catconcatenará los archivos de texto y mostrará el resultado en el terminal:

# File: fileinput-example.py
import fileinput
import sys

files = fileinput.input()
for line in files:
    if fileinput.isfirstline():
        print(f'n--- Reading {fileinput.filename()} ---')
    print(' -> ' + line, end='')
print()

Ejecutar esto en dos archivos de texto en mi directorio actual produce la siguiente salida:

$ python3 fileinput-example.py bacon.txt cupcake.txt
--- Reading bacon.txt ---
 -> Spicy jalapeno bacon ipsum dolor amet in in aute est qui enim aliquip,
 -> irure cillum drumstick elit.
 -> Doner jowl shank ea exercitation landjaeger incididunt ut porchetta.
 -> Tenderloin bacon aliquip cupidatat chicken chuck quis anim et swine.
 -> Tri-tip doner kevin cillum ham veniam cow hamburger.
 -> Turkey pork loin cupidatat filet mignon capicola brisket cupim ad in.
 -> Ball tip dolor do magna laboris nisi pancetta nostrud doner.

--- Reading cupcake.txt ---
 -> Cupcake ipsum dolor sit amet candy I love cheesecake fruitcake.
 -> Topping muffin cotton candy.
 -> Gummies macaroon jujubes jelly beans marzipan.

fileinputle permite recuperar más información sobre cada línea, como si es o no la primera línea (.isfirstline()), El número de línea (.lineno()), y el nombre de archivo (.filename()) . Puedes leer más al respecto aquí.

Conclusión

Ahora sabe cómo usar Python para realizar las operaciones más comunes en archivos y grupos de archivos. Usted ha aprendido acerca de los diferentes módulos incorporados que se utilizan para leer, encontrar y manipular.

Ahora está equipado para usar Python para:

  • Obtener contenidos de directorios y propiedades de archivos
  • Crear directorios y árboles de directorios
  • Encontrar patrones en nombres de archivo
  • Crear archivos y directorios temporales
  • Mover, renombrar, copiar y eliminar archivos o directorios
  • Leer y extraer datos de diferentes tipos de archivos
  • Leer varios archivos simultáneamente usandofileinput

Este tutorial tiene un curso de video relacionado creado por el equipo de Real Python. Míralo junto con el tutorial escrito para profundizar tu comprensión: Recetas prácticas para trabajar con archivos en Python

Enlaces Externos

Entradas relacionadas

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *