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 :
- https://docs.python.org/fr/3/library/pathlib.html#correspondence-to-tools-in-the-os-module
- https://docs.python.org/fr/3/library/pathlib.html
- https://realpython.com/python-pathlib/
- https://treyhunner.com/2018/12/why-you-should-be-using-pathlib/
- https://jefftriplett.com/2017/pathlib-is-wonderful/
- http://pbpython.com/pathlib-intro.html
L’idée de ce billet me vient de https://pythonbytes.fm/episodes/show/111/loguru-python-logging-made-simple.