create package and relative import
This commit is contained in:
parent
a76a76a07a
commit
abf82c6bdf
119
python.mdwn
119
python.mdwn
@ -1 +1,120 @@
|
|||||||
#Python
|
#Python
|
||||||
|
|
||||||
|
## Virtualenv et pip
|
||||||
|
|
||||||
|
### Aller voir SamEtMax
|
||||||
|
|
||||||
|
### Installer un package depuis des fichiers locaux
|
||||||
|
|
||||||
|
Rien de bien sorcier si le package est bien fait
|
||||||
|
|
||||||
|
pip install chemin/vers/le/package
|
||||||
|
|
||||||
|
Le chemin/vers/le/package peut être une archive tar.gz créé avec **python setup.py sdist**
|
||||||
|
|
||||||
|
## Créer un package près à installer avec pip
|
||||||
|
|
||||||
|
Le but de cette partie est d'expliquer comment ranger et mettre en forme les fichiers pythons pour permettre l'installation avec pip d'un package de notre cru.
|
||||||
|
|
||||||
|
### Forme du package
|
||||||
|
|
||||||
|
Un package a une forme particulière qui se présente ainsi
|
||||||
|
|
||||||
|
file/
|
||||||
|
LICENSE.txt
|
||||||
|
README.txt
|
||||||
|
MANIFEST
|
||||||
|
setup.py
|
||||||
|
moduleA/
|
||||||
|
__init__.py
|
||||||
|
moduleA.py
|
||||||
|
moduleB/
|
||||||
|
__init__.py
|
||||||
|
moduleB.py
|
||||||
|
|
||||||
|
Le fichier LICENSE.txt contient la licence du package.
|
||||||
|
Le fichier README.txt (à vérifier s'il ne peut pas être en markdown) voir [ici](http://guide.python-distribute.org/creation.html#readme-txt-description)
|
||||||
|
Le fichier MANIFEST contiendra la liste de tous les fichiers à inclure (s'il n'existe pas, il sera créé automatiquement).
|
||||||
|
Le fichier setup.py est le plus important. C'est lui qui décrit tout le package et qui va permettre l'installation (en particulier).
|
||||||
|
Ensuite on a les différents dossiers avec les modules. C'est là que le code est rangé. Même s'il est vide, il faut qu'il y est le fichier _ _ init _ _ .py .
|
||||||
|
|
||||||
|
Pour créer un setup.py basique, on adapte le contenu suivant:
|
||||||
|
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
from distutils.core import setup
|
||||||
|
|
||||||
|
setup(name='PackageName',
|
||||||
|
version='0.0.2',
|
||||||
|
description='A super description',
|
||||||
|
author='You, your friends, your fingers',
|
||||||
|
author_email='you@your.home',
|
||||||
|
url='http://www.python.org/sigs/distutils-sig/',
|
||||||
|
packages=['moduleA', 'moduleB'],
|
||||||
|
)
|
||||||
|
|
||||||
|
Les éléments de *packages* sont les noms des dossiers.
|
||||||
|
|
||||||
|
Pour plus d'info [documentation officiel](http://docs.python.org/2/distutils/setupscript.html).
|
||||||
|
|
||||||
|
Maintenant le packages est près à être distribué et installer (/!\ si dans le code les *import* ne sont pas fait correctement, l'exécution du package installé ne marchera pas - voir la partie *Relative import*).
|
||||||
|
|
||||||
|
Pour distribuer le package, on peut lancer la commande
|
||||||
|
|
||||||
|
python setup.py sdist
|
||||||
|
_
|
||||||
|
Elle aura pour effet de créer une archive du projet dans le répertoire *dist*.
|
||||||
|
|
||||||
|
### Relative import
|
||||||
|
|
||||||
|
Comme dit au dessus, quand on essaie de faire un package et que l'on veut l'utiliser, les chemins vers les différents fichiers sont modifiés et les import ne se font plus correctement. On a en général le droit à une belle erreur
|
||||||
|
|
||||||
|
ImportError: No module named ...
|
||||||
|
|
||||||
|
Imaginons que l'on soit dans cette configuration
|
||||||
|
|
||||||
|
moduleA/
|
||||||
|
moduleA1.py
|
||||||
|
moduleA2.py
|
||||||
|
|
||||||
|
Et que dans *moduleA2.py*, il y est
|
||||||
|
|
||||||
|
from moduleA1 import plop
|
||||||
|
|
||||||
|
Quand on lance depuis le dossier *moduleA*
|
||||||
|
|
||||||
|
python moduleA2
|
||||||
|
|
||||||
|
pas de soucis.
|
||||||
|
|
||||||
|
Par contre si l'on a installé notre package et que l'on veut import le moduleA2, on a alors l'erreur
|
||||||
|
|
||||||
|
ImportError: No module named moduleA1
|
||||||
|
|
||||||
|
Cela est dû aux chemins qui ont été modifiés.
|
||||||
|
|
||||||
|
Pour résoudre ce soucis, il va falloir convertir l'import absolue du moduleA2 en import relatif. Pour cela, il faut ajouter un "." devant de nom du module.
|
||||||
|
|
||||||
|
from .moduleA1 import plop
|
||||||
|
|
||||||
|
Maintenant l'import du package moduleA2 marche mais plus sont "lancement" qui renvoie l'erreur
|
||||||
|
|
||||||
|
SystemError: Parent module '' not loaded, cannot perform relative import
|
||||||
|
|
||||||
|
Pas très pratique... Pour refaire marcher le lancement, il faut se placer dans le répertoire parent de *moduleA* et lancer
|
||||||
|
|
||||||
|
python -m moduleA.moduleA2
|
||||||
|
|
||||||
|
## Quelques reférences
|
||||||
|
|
||||||
|
### Virtualenv et pip
|
||||||
|
|
||||||
|
* http://docs.python.org/2/distutils/setupscript.html
|
||||||
|
|
||||||
|
### Créer son package
|
||||||
|
|
||||||
|
* http://docs.python.org/2/distutils/setupscript.html
|
||||||
|
|
||||||
|
### Relative import
|
||||||
|
|
||||||
|
* https://www.inkling.com/read/learning-python-mark-lutz-4th/chapter-23/why-use-package-imports
|
||||||
|
Loading…
Reference in New Issue
Block a user