Una introducción al módulo pathlib en Python

Ante que nada, me gustaria aclarar algo que quizas suene muy evidente, pero que de hecho algunas veces olvidamos, y es que una ruta o path no es una cadena, y este hecho es algo que debemos siempre tener en cuenta, ya que nos ahorrara muchos dolores de cabeza. A partir de la versión 3.4 de Python contamos con un poderoso y versatil módulo llamado pathlib.

En este breve articulo quiero compartir con ustedes sobre algunas funciones especificas que creo podrán ser de mucha ayuda y que te permitira programar en una forma más simple y agil muchas tareas relacionadas con la gestión de operaciones en nuestro sistema operativo con Python.

Por otro lado, quiero mencionar los siguientes puntos que creo son importantes y que nos permitiran estar prevenidos al momento de interactuar con las tareas a nivel del SO (Sistema Operativo).

  1. Ruta absoluta: Esta inicia en el folder o directorio raiz, por ejemplo en Linux: /home/ ; y en Window es C:\
  2. Ruta relativa: Es aquella relativa al directorio de trabajo de tu aplicación.
  3. Cada Sistema Operativo (SO) usa un separador especifico. Linux y Mac usan /, mientras que Windows usa \.

El modulo pathlib simplifica de una manera dramatica la cantidad de codigo requerido para trabajar con directorios y archivos. A través de este articulo quiero mostrarte una serie de ejemplos con algunos beneficios claves de usar este módulo, pero principalmente como hacer nuestro código mas legible y fácil de mantener.

Aquí te presento un ejemplo simple y multiplataforma, donde obtenemos el directorio principal asociado con el usuario que ejecuta el metódo en Python. El primer paso consiste en importar el módulo, para fines didacticos y por simplicidad estaremos permitiendo el uso de todas las clases contenidas dentro del módulo.

import pathlib
return pathlib.Path().home()

En caso de ejecutar la sentencia anterior en Windows deberias obtener una salida como la siguiente:

C:\Users\Your_UserName

En Linux la salida deberia ser algo similar a:

/home/Your_UserName

Otra función muy util que forma parte de pathlib es cwd, que corresponde a las iniciales “current working directory” (directorio actual de trabajo), como en el siguiente ejemplo:

pathlib.Path.cwd()

La salida esperada en tu caso deberia corresponder a tu directorio de trabajo, en este caso es similar al valor retornado por la función os.getcwd .  Tipicamente para la composición de una ruta podemos hacer uso del simbolo / para anexar una directorio o el nombre de un archivo como si estuvieramos tratando con una cadena, por ejemplo:

pathlib.Path().home()/ 'mydirectory' /'myfile.py'

Como has podido ver en los ejemplos anteriores, no nos hemos preocupado en la manera en que Python gestiona las rutas dentro del Sistema Operativo (SO) , este punto es clave y quizas una de los principales ventajas a tomar en cuenta para comenzar a usar el módulo pathlib. Probablemente puedas encontrar algunos metódos comunes a los que se usaban en módulos legacy comos os

Ahora, imagina que tenemos un proyecto que requerimos ejecutar bajo una localización parametrizada y especifica, y es aquí donde vamos a hacer uso de una función que nos permita obtener la ruta absoluta basada en el directorio de ejecución de nuestra aplicación, la siguiente opción es la más adecuada:

def absolutepath():
    return pathlib.Path().absolute()

Permitame agregar un poco de dinamismo y construir una simple función la cuál reciba un nombre de archivo y debera retornar la ruta completa a traves de la concatenación con la función joinpath.

def getPathFileName(fileName):
    path = pathlib.Path().cwd()
    return pathlib.Path.joinpath(path, fileName)

En caso que necesitemos verificar que la ruta y definición de un archivo es válido antes de ejecutar cualquier acción, contamos con una función perfecta para estos casos, esta es is_file function, por lo que podremos usar este metódo antes de decidir ejecutar cualquier acción.

(pathlib.Path.home() / 'mypython.txt').is_file()

Así como tenemos una función para conocer si la ruta de un archivo es válida, igualmente contamos con una función que nos da la capacidad de saber si una ruta representa un directorio válido, aquí un ejemplo.

(pathlib.Path.home() / 'mydirectory').is_dir()

En algunos casos, necesitamos verificar si un archivo especifico existe dentro de una localización , por lo que pathlib nos ofrece otro metódo simple para llevarlo a cabo.

os.path.exists(filename_expected_here)

El siguiente ejemplo estará combinando dos funciones para eliminar un archivo si este existe.

def removeFile(file_name):
    if os.path.exists(file_name):
        os.remove(file_name)

Finalmente, estaremos abordando una forma efectiva de listar y filtrar todos los archivos que tengan una extension especifica, en este caso, estaremos trabajando desde nuestro directorio de trabajo en Python y filtrando todos los archivos .py, esta vez usaremos el metódo Path.glob(pattern), a partir de un patron relativo en el directorio de nuestra ruta, este retornara todos los archivos requeridos y finalmente iteraremos sobre el objecto resultante, permitame mostrarte el ejemplo completo.

def getAllPythonFiles():
    return pathlib.Path('.').glob('**/*.py')

files = getAllPythonFiles()
for f in files:
    print(f.name)

Como la documentación oficial de Python afirma: “el patron «**» significa «este directorio y todos los subdirectorios en una forma recursiva”, finalmente el simbolo / es usado para permitir que el interprete reconozca el caracter siguiente como un literal, en este caso significa todos los archivos *.py (sin importar el nombre del archivo) con la extensión .py.

Espero que este articulo haya resultado de vuestro interes , este sera el primero de una serie dedicado a pathlib y otros módulos que pueden resultarles de utilidad para interactuar con el sistema operativo a través de Python.  Happy coding!!!