2009-05-19 11 views
3

Dans un système Python pour lequel je développe, nous avons généralement cette structure de module. Ceci permet à notre petit framework de test d'importer facilement test/feature.py et d'exécuter des tests unitaires. Cependant, nous avons maintenant le besoin de certains scripts shell (qui sont écrits en Python):Importations Python: importer un module sans extension .py?

mymodule/ 
mymodule/scripts/yetanotherfeature.py 
mymodule/test/yetanotherfeature.py 

yetanotherfeature.py est installé par le module paquet Debian dans/usr/bin. Mais nous ne voulons évidemment pas l'extension .py là. Ainsi, pour que le cadre de test pour être encore en mesure d'importer le module que je dois faire ce lien symbolique thingie:

mymodule/ 
mymodule/scripts/yetanotherfeature 
mymodule/scripts/yetanotherfeature.py @ -> mymodule/scripts/yetanotherfeature 
mymodule/test/yetanotherfeature.py 

Est-il possible d'importer un module par nom de fichier en Python, ou pouvez-vous penser à un solution plus élégante pour cela?

+2

Quel est le problème avec le lien symbolique? C'est la manière la plus élégante de gérer cela; vous devriez l'utiliser pour le déploiement, aussi./usr/bin/feature est un lien vers /usr/bin/feature.py fonctionne bien en rendant l'implémentation claire. –

Répondre

1

Vous pouvez probablement utiliser certains Tricker en utilisant l'importation hooks, je ne le recommanderais pas bien. D'un autre côté, je ferais aussi probablement l'inverse, j'ai des scripts .py quelque part, et je fais des liens symboliques avec les fichiers .py. Ainsi, votre bibliothèque peut être n'importe où et vous pouvez exécuter le test de l'intérieur en l'important normalement (puisqu'il a l'extension py), puis/usr/bin/yetanotherfeature pointe dessus, donc vous pouvez l'exécuter sans le py.

Edit: Passons ce (au moins la partie de crochets), la solution de diablotin d'importation est très bon pour moi :)

+0

En fait, je pense que c'est probablement le plus logique. La conception actuelle semble un peu erronée :) – pojo

9

Le imp module est utilisé pour cela:

[email protected]:/tmp/test$ cat mymodule 
print "woho!" 
[email protected]:/tmp/test$ cat test.py 
import imp 
imp.load_source("apanapansson", "mymodule") 
[email protected]:/tmp/test$ python test.py 
woho! 
[email protected]:/tmp/test$ 
+3

Ceci crée un fichier appelé "mymodulec". C'est censé être le .pyc, mais comme le fichier original ne se terminait pas en .py, il attachait juste un c à la fin. C'est bizarre. Puis-je le faire ne pas le faire? –

+0

Si vous ne voulez pas que "mymodulec" soit créé, définissez 'sys.dont_write_bytecode = True' –

+0

Notez que imp.load_source est obsolète, mais toujours dans python 2.7. Pour python 3.3, voir [Importer n'importe quel fichier source python. (Python 3.3+) - Dépassement de pile] (http://stackoverflow.com/questions/19009932/import-abitrary-python-source-file-python-3-3).Pour plus de clarté sur ce qu'est l'argument name ("apanapansson" ici), voir [python - chargement des modules par imp.load_source avec le même nom résultant de la fusion des modules - Stack Overflow] (http://stackoverflow.com/questions/ 15082857/chargement-modules-par-imp-charge-source-avec-même-nom-résultant-fusion-du-module). – nealmcb

0

Une autre option serait d'utiliser setuptools:

» ... il y a Il n'est pas facile de faire correspondre les noms de fichier d'un script aux plates-formes Windows et POSIX, mais vous devez souvent créer un fichier séparé pour le script "main", lorsque votre "main" est une fonction dans un module quelque part ... setuptools résout tous ces problèmes en générant automatiquement des scripts pour vous avec l'extension correcte, et sur Windows, il créera même un fichier .exe ... "

https://pythonhosted.org/setuptools/setuptools.html#automatic-script-creation

Questions connexes