create package and relative import

This commit is contained in:
Lafrite 2014-02-08 06:17:20 +01:00
parent a76a76a07a
commit abf82c6bdf

View File

@ -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