Introducción al módulo Python Pathlib

El módulo Pathlib en Python simplifica la forma de trabajar con archivos y carpetas. El módulo Pathlib está disponible desde Python 3.4 y versiones superiores. Combina...

El módulo Pathlib en Python simplifica la forma de trabajar con archivos y carpetas. El módulo Pathlib está disponible desde Python 3.4 y versiones superiores. Combina lo mejor de los módulos del sistema de archivos de Python, a saber, sistema operativo, [os.ruta](https://docs.python .org/3/library/os.path.html), globo, etc.

En Python, la mayoría de los scripts involucran la interacción con sistemas de archivos. Por lo tanto, es importante ocuparse de los nombres y las rutas de los archivos. Para lograr esto, Python incluye el módulo Pathlib que contiene funciones útiles para realizar tareas relacionadas con archivos. Pathlib proporciona una forma más legible y fácil de crear rutas al representar las rutas del sistema de archivos como objetos adecuados y nos permite escribir código que es portátil entre plataformas.

En este artículo, estudiaremos el módulo Pathlib en detalle con la ayuda de varios ejemplos.

El concepto de ruta y directorio

Antes de continuar con los detalles del módulo Pathlib, es importante comprender 2 conceptos diferentes, a saber: ruta y directorio.

La ruta se utiliza para identificar un archivo. La ruta proporciona una secuencia opcional de nombres de directorio terminados por el nombre de archivo final, incluida la extensión del nombre de archivo. La extensión del nombre de archivo proporciona información sobre el formato/contenido del archivo. El módulo Pathlib puede manejar rutas absolutas y relativas. Una ruta absoluta comienza desde el directorio raíz y especifica el árbol de directorios completo, mientras que una ruta relativa, como sugiere el nombre, es la ruta de un archivo en relación con otro archivo o directorio (generalmente el directorio actual).

El directorio representa la entrada del sistema de archivos de la ruta e incluye el nombre del archivo, la hora de creación, el tamaño, el propietario, etc.

El módulo Pathlib en Python se ocupa de las tareas relacionadas con las rutas, como la construcción de nuevas rutas a partir de los nombres de los archivos y de otras rutas, la verificación de varias propiedades de las rutas y la creación de archivos y carpetas en rutas específicas.

¿Cómo usar el módulo Pathlib?

Para usar el módulo pathlib convenientemente dentro de nuestros scripts, importamos todas las clases en él usando:

1
from pathlib import *

Como primera tarea, recuperemos el directorio de trabajo actual y los objetos del directorio de inicio, respectivamente, usando el siguiente código:

1
2
3
4
current_dir = Path.cwd()
home_dir = Path.home()
print(current_dir)
print(home_dir)

Podemos elegir importar pathlib en lugar de importar todas las clases. En ese caso, todos los usos posteriores de clases dentro del módulo deben tener el prefijo pathlib.

1
2
3
4
5
6
import pathlib

current_dir = pathlib.Path.cwd()
home_dir = pathlib.Path.home()
print(current_dir)
print(home_dir)

¿Por qué usar el módulo Pathlib? {#por qué usar el módulo pathlib}

Si ha estado trabajando con el lenguaje Python por un tiempo, se preguntará cuál es la necesidad del módulo Pathlib cuando los módulos os, os.path, glob, etc. ya están disponibles. Esta es una preocupación totalmente justificada. Intentemos abordar esto a través de un ejemplo.

Digamos que queremos crear un archivo llamado "output/output.xlsx" dentro del directorio de trabajo actual. El siguiente código intenta lograr esto utilizando el módulo os.path. Para ello se utilizan las funciones os.getcwd y os.path.join.

1
2
3
import os
outpath = os.path.join(os.getcwd(), 'output')
outpath_file = os.path.join(outpath, 'out.xlsx')

Alternativamente,

1
outpath_file = os.pathjoin(os.path.join(os.getcwd(), 'output'), "out.xlsx")

Aunque el código funciona, parece torpe y no es legible ni fácil de mantener. Imagine cómo se vería este código si quisiéramos crear un nuevo archivo dentro de varios directorios anidados.

El mismo código se puede reescribir usando el módulo Pathlib, de la siguiente manera:

1
2
from pathlib import Path
outpath = Path.cwd() / 'output' / 'output.xlsx'

Este formato es más fácil de analizar mentalmente. En Pathlib, la función Path.cwd() se usa para obtener el directorio de trabajo actual y el operador / se usa en lugar de os.path.join para combinar partes de la ruta en un objeto de ruta compuesta. El patrón de anidamiento de funciones en el módulo os.path se reemplaza por la clase Path del módulo Pathlib que representa la ruta mediante el encadenamiento de métodos y atributos. La sobrecarga inteligente del operador / hace que el código sea legible y fácil de mantener.

Otro beneficio del método proporcionado por el módulo Pathlib es que se crea un objeto Path en lugar de crear una representación de cadena de la ruta. Este objeto tiene varios métodos prácticos que hacen la vida más fácil que trabajar con cadenas sin procesar que representan rutas.

Realización de operaciones en rutas {#realización de operaciones en rutas}

El módulo clásico os.path se usa solo para manipular cadenas de ruta. Para hacer algo con la ruta, por ejemplo, crear un directorio, necesitamos el módulo os. El módulo os proporciona un conjunto de funciones para trabajar con archivos y directorios, como: mkdir para crear un directorio, rename para cambiar el nombre de un directorio, getsize para obtener el tamaño de un directorio, etc.

Escribamos algunas de estas operaciones usando el módulo os y luego reescribamos el mismo código usando el módulo Pathlib.

Ejemplo de código escrito usando el módulo os:

1
2
if os.path.isdir(path):
    os.rmdir(path)

Si usamos los objetos path del módulo Pathlib para lograr la misma funcionalidad, el código resultante será mucho más legible y fácil de mantener, como se muestra a continuación:

1
2
if path.is_dir()
    path.rmdir()

Es engorroso encontrar utilidades relacionadas con rutas en el módulo os. El módulo Pathlib resuelve el problema reemplazando las utilidades del módulo os con métodos en objetos de ruta. Entendámoslo aún mejor con un código:

1
2
3
4
5
6
7
8
outpath = os.path.join(os.getcwd(), 'output')
outpath_tmp = os.path.join(os.getcwd(), 'output.tmp')
generate_data(output_tmp)

if os.path.getsize(output_tmp):
    os.rename(outpath_tmp, outpath)
else: # Nothing produced
    os.remove(outpath_tmp)

Aquí, la función generate_data() toma una ruta de archivo como parámetro y escribe datos en otra ruta. Sin embargo, si el archivo que se pasa como parámetro no se modifica desde la última vez que se ejecutó la función generar_datos(), se genera un archivo vacío. En ese caso, el archivo vacío se reemplaza con la versión anterior del archivo.

La variable outpath almacena los datos al unir el directorio de trabajo actual con el nombre de archivo "output". También creamos una versión temporal, llamada outpath.tmp. Si el tamaño de la versión temporal no es cero, lo que implica que no es un archivo vacío, entonces se cambia el nombre de la versión temporal a outpath; de lo contrario, se elimina la versión temporal y se conserva la versión anterior.

Usando el módulo os, la manipulación de rutas de sistemas de archivos como objetos de cadena se vuelve torpe ya que hay múltiples llamadas a os.path.join(), os.getcwd(), etc. Para evitar este problema, el módulo Pathlib ofrece un conjunto de clases que se pueden usar para operaciones de uso frecuente en la ruta, de una manera más legible, simple y orientada a objetos.

Intentemos volver a escribir el código anterior usando el módulo Pathlib.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
from pathlib import Path

outpath = Path.cwd() / 'output'
outpath_tmp = Path.cwd() / 'output_tmp'

generate_data(output_tmp)

if outpath_tmp.stat().st_size:
    outpath_tmp.rename(outpath)
else: # Nothing produced
    Path_tmp.unlink()

Usando Pathlib, os.getcwd() se convierte en Path.cwd() y el operador '/' se usa para unir rutas y se usa en lugar de os.path.join. Usando el módulo Pathlib, las cosas se pueden hacer de una manera más simple usando operadores y llamadas a métodos.

Los siguientes son métodos comúnmente utilizados y su uso:

  • Path.cwd(): objeto de ruta de retorno que representa el directorio de trabajo actual
  • Path.home(): objeto de ruta de retorno que representa el directorio de inicio
  • Path.stat(): devuelve información sobre la ruta
  • Path.chmod(): cambia el modo de archivo y los permisos
  • Path.glob(pattern): Glob el patrón dado en el directorio que está representado por la ruta, produciendo archivos coincidentes de cualquier tipo
  • Path.mkdir(): para crear un nuevo directorio en la ruta dada
  • Path.open(): Para abrir el archivo creado por la ruta
  • Path.rename(): Cambia el nombre de un archivo o directorio al objetivo dado
  • Path.rmdir(): Eliminar el directorio vacío
  • Path.unlink(): Elimina el archivo o enlace simbólico

Generación de rutas multiplataforma

Las rutas usan diferentes convenciones en diferentes sistemas operativos. Windows usa una barra invertida entre los nombres de las carpetas, mientras que todos los demás sistemas operativos populares usan una barra diagonal entre los nombres de las carpetas. Si desea que su código python funcione, independientemente del sistema operativo subyacente, deberá manejar las diferentes convenciones específicas de la plataforma subyacente. El módulo Pathlib facilita el trabajo con rutas de archivos. En Pathlib, puede simplemente pasar una ruta o nombre de archivo al objeto Path() usando una barra inclinada, independientemente del sistema operativo. Pathlib se encarga del resto.

1
pathlib.Path.home() / 'python' / 'samples' / 'test_me.py'

El objeto Path() convertirá el / en el tipo de barra oblicua adecuada, para el sistema operativo subyacente. pathlib.Path puede representar la ruta de Windows o Posix. Por lo tanto, Pathlib resuelve muchos errores interfuncionales al manejar las rutas fácilmente.

Obtener información de la ruta

Al tratar con rutas, estamos interesados ​​en encontrar el directorio principal de un archivo/carpeta o en seguir enlaces simbólicos. La clase de ruta tiene varios [métodos] (https://docs.python.org/3/library/pathlib.html) convenientes para hacer esto, ya que las diferentes partes de una ruta están disponibles como propiedades que incluyen lo siguiente:

  • unidad: una cadena que representa el nombre de la unidad. Por ejemplo, PureWindowsPath('c:/Program Files/CSV').drive devuelve "C:"
  • parts: devuelve una tupla que proporciona acceso a los componentes de la ruta
  • name: el componente de ruta sin ningún directorio
  • padre: secuencia que proporciona acceso a los ancestros lógicos de la ruta
  • stem: componente de ruta final sin su sufijo
  • sufijo: la extensión de archivo del componente final
  • ancla: la parte de una ruta antes del directorio. / se usa para crear rutas secundarias e imita el comportamiento de os.path.join.
  • joinpath: combina la ruta con los argumentos proporcionados
  • coincidir (patrón): devuelve Verdadero/Falso, basado en hacer coincidir la ruta con el patrón de estilo global proporcionado

En la ruta "/home/projects/wikihtp/python/sample.md":

  • ruta: - devuelve PosixPath('/home/projects/wikihtp/python/sample.md')
  • path.parts: - devuelve ('/', 'home', 'projects', 'wikihtp', 'python')
  • ruta.nombre: - devuelve 'muestra.md'
  • path.stem: - devuelve 'muestra'
  • ruta.sufijo: - devuelve '.md'
  • path.parent: - devuelve PosixPath('/home/projects/wikihtp/python')
  • path.parent.parent: - devuelve PosixPath('/home/projects/wikihtp')
  • path.match('*.md'): devuelve Verdadero
  • PurePosixPath('/python').joinpath('edited_version'): devuelve ('home/projects/wikihtp/python/edited_version

Alternativa del módulo global

Además de los módulos os, os.path, el módulo glob también está disponible en Python y proporciona utilidades relacionadas con la ruta del archivo. La función glob.glob del módulo glob se usa para encontrar archivos que coincidan con un patrón.

1
2
3
4
from glob import glob

top_xlsx_files = glob('*.xlsx')
all_xlsx_files = glob('**/*.xlsx', recursive=True)

Pathlib también proporciona utilidades globales:

1
2
3
4
from pathlib import Path

top_xlsx_files = Path.cwd().glob('*.xlsx')
all_xlsx_files = Path.cwd().rglob('*.xlsx')

La funcionalidad global está disponible con los objetos Path. Por lo tanto, los módulos pathlib simplifican las tareas complejas.

Lectura y escritura de archivos usando Pathlib {#lectura y escritura de archivos usando pathlib}

Los siguientes métodos se utilizan para realizar operaciones básicas como leer y escribir archivos:

  • read_text: el archivo se abre en modo texto para leer el contenido del archivo y cerrarlo después de leerlo
  • read_bytes: Se usa para abrir el archivo en modo binario y devolver el contenido en forma binaria y cierra el archivo después de lo mismo.
  • write_text: se usa para abrir el archivo y escribe texto y lo cierra más tarde
  • write_bytes: se usa para escribir datos binarios en un archivo y cierra el archivo, una vez hecho

Exploremos el uso del módulo Pathlib para operaciones de archivos comunes. El siguiente ejemplo se utiliza para leer el contenido de un archivo:

1
2
path = pathlib.Path.cwd() / 'Pathlib.md'
path.read_text()

Aquí, el método read_text en el objeto Path se usa para leer el contenido del archivo.
El siguiente ejemplo se usa para escribir datos en un archivo, en modo de texto:

1
2
3
from pathlib import Path

p = Path('sample_text_file') p.write_text('Sample to write data to a file')

Por lo tanto, en el módulo Pathlib, tener la ruta como un objeto nos permite realizar acciones útiles en los objetos para el sistema de archivos que involucran mucha manipulación de rutas, como crear o eliminar directorios, buscar archivos específicos, mover archivos, etc.

Conclusión

Para concluir, el módulo Pathlib proporciona una gran cantidad de características ricas y útiles que se pueden usar para realizar una variedad de operaciones relacionadas con rutas. Como ventaja adicional, la biblioteca es coherente en todo el sistema operativo subyacente.

Licensed under CC BY-NC-SA 4.0