Utilisez pathlib plutôt qu’os.path ou glob

Cet article de blog a été déplacé sur mon nouveau site, vous le trouverez ici : https://www.lecalamar.fr/posts/2019-01-15-utilisez-pathlib-au-lieu-d-os-path-ou-glob/

Régulièrement, en programmant en Python, nous sommes amenés à utiliser des chemins de fichiers, de dossiers, et à les manipuler. Python fournit de quoi les manipuler simplement. Contrairement à de la vieille documentation (et sauf raisons valables), vous n’êtes censés utiliser que la nouvelle API fournie par pathlib.

À noter aussi que vous n’avez plus à vous préoccuper des slashs ou anti-slashs selon les systèmes d’exploitation, mettez ce que vous voulez, pathlib s’occupe du reste !

« Un exemple de code » me direz vous. Et bien voici :

import os

in_file = os.path.join(os.path.join(os.getcwd(), "in"), "input.xlsx")
out_file = os.path.join(os.path.join(os.getcwd(), "out"), "output.xlsx")

Devient avec pathlib :

from pathlib import Path

in_file = Path.cwd() / "in" / "input.xlsx"
out_file = Path.cwd() / "out" / "output.xlsx"

Ceci a le mérite d’être facile à lire, et fonctionne grâce à la surcharge de l’opérateur de division.

Et si, par exemple, vous avez des projets django, vous avez dû écrire des configurations comme :

import os


# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.sqlite3",
        "NAME": os.path.join(BASE_DIR, "db.sqlite3"),
    }
}

En utilisant pathlib, ce code devient plus lisible :

from pathlib import Path


# Build paths inside the project like this: BASE_DIR / "..."
BASE_DIR = Path(__file__).resolve().parent.parent

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.sqlite3",
        "NAME": BASE_DIR / "db.sqlite3",
    }
}

De plus pathlib fournit les différentes fonctions très pratiques.

import os
import os.path

os.makedirs(os.path.join('src', '__pypackages__'), exist_ok=True)
os.rename('.editorconfig', os.path.join('src', '.editorconfig'))

Devient

from pathlib import Path

Path('src/__pypackages__').mkdir(parents=True, exist_ok=True)
Path('.editorconfig').rename('src/.editorconfig')
# ou encore
Path('src', '__pypackages__').mkdir(parents=True, exist_ok=True)
Path('.editorconfig').rename(Path('src', '.editorconfig'))

Ou encore

import glob

configfiles = glob.glob(
    '/home/vincent/dossier1/**/*.ini',
    recursive=True)

Devient

from pathlib import Path

configfiles = Path('/home/vincent/dossier1/').rglob('*.ini')

Ou encore

from glob import glob

file_contents = []
for filename in glob('**/*.py', recursive=True):
    with open(filename) as python_file:
        file_contents.append(python_file.read())

Devient

from pathlib import Path

file_contents = [
    path.read_text()
    for path in Path.cwd().rglob('*.py')
]

Enfin, plein de bonnes choses sont accessibles, par exemple :

if Path('docs/README.md').is_file():

Bref, je vous conseille de jeter un coup d’œil à ce fameux pathlib.

Il m’intriguait depuis longtemps. Un bon moyen de savoir ce qu’il fait a été, pour moi, de traduire la documentation en français. Elle est maintenant accessible à cette adresse : https://docs.python.org/fr/3/library/pathlib.html.

Vous pourrez en savoir plus en lisant :

L’idée de ce billet me vient de https://pythonbytes.fm/episodes/show/111/loguru-python-logging-made-simple.

Laisser un commentaire

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur la façon dont les données de vos commentaires sont traitées.