URL: https://linuxfr.org/users/oliver_h/journaux/quelques-bonnes-pratiques-python-pour-2019 Title: Quelques bonnes pratiques Python pour 2019 Authors: Oliver Date: 2019年03月30日T19:22:55+01:00 License: CC By-SA Tags: python, python2 et python3 Score: 22 J'ai découvert/appris Python en le pratiquant au bureau à l'arche, et sans collègue à la fois expert et pédagogue. Du coup, j'ai accumulé plein de mauvaises pratiques que je tente désormais de corriger. Ce journal pour vous partager mes astuces et vous éviter les mêmes pièges :-) Je ne suis pas encore un expert Python, alors merci de me corriger gentiment dans les commentaires ;-) Je publie ce journal sous [[licence CC0]] (sous domaine publique dans les pays où cela et possible) car je veux te permettre de recopier/modifier/réutiliser/republier ce contenu sans avoir à me citer comme auteur (sauf que la loi de pays comme la France t'oblige quand même à me citer). Installer des modules Python ============================ Le gestionnaire de paquets Python de référence s'appelle `pip` et au tout début, j'installais les dépendances Python manquantes avec : ``` sudo pip install "nom-du-module-python" # en root ``` car cette commande ne semblait pas toujours fonctionner : ``` pip install "nom-du-module-python" ``` En fait la première commande ci-dessus rentre en conflit avec : ``` sudo apt install "autre-nom-du-meme-module-python" ``` Ça fout le bazar dans l'installation des paquets de sa distrib... :-( ![Voilà à quoi ressemble mon installation avec `sudo pip` et `sudo apt`](https://staff.napier.ac.uk/services/secretary/governance/records/email/PublishingImages/BadDesk.jpg "Voilà à quoi ressemble mon installation avec pip et apt") En lisant [pip ticket #5599](https://github.com/pypa/pip/issues/5599) on comprend le besoin de préciser l'argument `--user`: ``` pip install --user "nom-du-module-python" ``` Mais il y a mieux: ``` python -m pip install --user "nom-du-module-python" ``` Et encore mieux si nos scripts ont migré sous Python-3: ``` python3 -m pip install --user "nom-du-module-python" ``` Donc, remettons bien en gras les bonne façons d'installer un module Python: ## `python2 -m pip install --user "nom-du-module-python"` ## `python3 -m pip install --user "nom-du-module-python"` Mais quelle différence entre `pip3` et `python3 -m pip` ? Les détails sur [stackoverflow](https://stackoverflow.com/q/25749621/938111) (en anglais). En bref, on est sûr que `python3 -m pip` utilise la même arborescence d'installation que le script que tu exécutes avec `python3 "nom-du-script.py"`. C'est d'autant plus recommandé si ton `$PATH` est tarabiscoté, si tu as plusieurs installations de Python ou que tu utilises MS-Windows. Mettre à jour les modules Python ================================ Est-ce que `pip` permet de mettre à jour tous les modules d'un coup comme un `apt upgrade` ? Et bien, pas vraiment. Il faut le faire pour chaque module : ``` python3 -m pip install --user --upgrade "nom-du-module-python" ``` Attention, j'ai déjà réussi à casser `pip` avec cette commande : ``` pip install --upgrade pip ``` Pour tout mettre à jour, j'enregistre préalablement les versions des modules actuellement présents : ``` python3 -m pip list --user --format freeze> ~/requirements_avant_pip_upgrade.txt ``` Et une longue ligne de commande pour tout mettre à jour : ``` python3 -m pip list --user --format columns | awk 'FNR>2{print 1ドル}' | while read module ; do python3 -m pip install --user --upgrade $module ; done ``` Visualiser les changements : ``` python3 -m pip list --user --format freeze> ~/requirements_apres_pip_upgrade.txt diff -u ~/requirements_avant_pip_upgrade.txt ~/requirements_apres_pip_upgrade.txt | vi - # quitter en tapant :q! [Entrée] ``` Ou avec une application graphique : ``` meld ~/requirements_avant_pip_upgrade.txt ~/requirements_apres_pip_upgrade.txt ``` En cas de problème, revenir aux versions précédentes : ``` python3 -m pip install --user -r ~/requirements_avant_pip_upgrade.txt ``` En fait, ce n'est pas recommandé de mettre à jour tous ses modules Python car cela risquerait de casser une autre application Python qui utilise la même dépendance. Cela m'est arrivé récemment avec le module `redis` dont la [version 3 casse la comptabilité avec la version 2](https://pypi.org/project/redis/#upgrading-from-redis-py-2-x-to-3-0) ! (mais pourquoi ne pas avoir créé de nouvelles fonctions pour la nouvelle fonctionnalité ?) Rendre un script exécutable =========================== Pour lancer leur script Python, de nombreuses personnes font : ``` python mon-script.py ``` Avec deux petits changements, il est possible de le lancer juste comme ça : ``` ./mon-script.py ``` Premier changement, dire que le script est exécutable : ``` chmod +x mon-script.py ``` Second changement, on rajoute sur LA PREMIÈRE ligne du fichier `mon-script.py` : ```sh #!/1usr/bin/python ``` Ou mieux : ```sh #!/usr/bin/python3 ``` Ou encore bien mieux : ```sh #!/usr/bin/env python3 ``` Le `#!` s'appelle [[shebang]] et même des langages dont le `#` n'est pas utilisé pour les commentaires le prennent en charge, comme pour [PHP](https://www.php.net/manual/fr/features.commandline.usage.php#example-422). Compatibilité Python-2 et Python-3 ================================== Les distributions GNU/Linux sont enfin en train de migrer tous leurs scripts vers Python-3 (Pyton-3.0 a 10 ans). Mais difficile d'identifier si un script est compatible seulement v2 ou seulement v3 ou s'il est compatible avec les deux. Pour aider les intégrateurs, merci de remplacer `python` par `python2` ou `python3` dans vos projets open-source. Et si compatible avec les deux versions de Python ? Si ton application compatible v2 et v3 pourrait être utilisée sur une ancienne distribution GNU/Linux qui n'a pas Python3, alors continue d'utiliser `python`. Si ce n'est pas le cas, utilise alors `python3`. Pour s'assurer que tes scripts Python2 soient compatibles Python3 rajoute au début de tous tes fichiers `*.py` : ```py from __future__ import absolute_import, division, unicode_literals, print_function ``` Attention, je me suis fait avoir avec un bug uniquement reproductible avec la ligne précédente. Quand je lançais `python2` en mode interactif pour vérifier mon bout de code, je n'avais aucun soucis. Donc pense à taper `from __future__ import absolute_import, division, unicode_literals, print_function` quand tu veux reproduire un bug dans ton script python2. Il y a moyen de pré-exécuter cette ligne automatiquement. Avec `ipython` : ``` $ cat ~/.ipython/profile_default/startup/ipython_config.py from __future__ import absolute_import, division, unicode_literals, print_function ``` Arborescence d'un projet Python =============================== Kenneth Reitz recommandait https://github.com/kennethreitz/samplemod docs\ sample\ tests\ LICENSE MANIFEST.in Makefile README.rst requirements.txt setup.py Plus récemment, l'équipe *Python Packaging Autority* recommande https://github.com/pypa/sampleproject data\ sample\ tests\ LICENSE.txt MANIFEST.in README.md # PyPi accepte Markdown depuis 2018 setup.cfg # Alternative à setup.py setup.py tox.ini # Plus besoin de requirements-test.txt Si tu préfères [[Markdown]] à [[reStructuredText]], sache que [PyPi gère même les tableau Markdown](https://blog.thea.codes/github-flavored-markdown-on-pypi/). Mais une révolution est en cours avec les [PEP-517](https://www.python.org/dev/peps/pep-0517/) et [PEP-518](https://www.python.org/dev/peps/pep-0518/), avec l'adoption du fichier `pyproject.toml` en alternative du vénérable `setup.py` et son `setup.cfg` (même `pip` adopte `pyproject.toml`). Mais la vrai révolution est le découplage entre empaquetage et installation. Pour les anglophones je recommande la lecture de [Python packaging - Past, Present, Future](https://www.bernat.tech/pep-517-518/) par Bernát Gábor. Donc bientôt nous pourrons avoir une arborescence plus simple : docs\ sample\ tests\ LICENSE.txt README.md pyproject.toml tox.ini Par exemple, les dépôts de code source de [`poetry`](https://github.com/sdispater/poetry) et de la [PEP-517](https://github.com/pypa/pep517/). Et tes astuces ? ================ Merci de partager tes recommandations, tes mésaventures, tes bonne pratiques... :-D

AltStyle によって変換されたページ (->オリジナル) /