L'exécution du script python depuis virtualenv bin ne fonctionne pas

J'ai un script que je veux être disponible globalement. Je l'ai commencé avec le hashbang standard:

#! /usr/bin/env python

Et l'a lié dans le répertoire bin de mon virtualenv:

~/environments/project/env/bin/myscript

Et ajouté ce répertoire à mon chemin. Quand j'exécute la commande:

myscript

Je reçois une erreur d'importation avec l'une des bibliothèques. Cependant, si j'active l'environnement virtuel et exécute le script, cela fonctionne comme prévu.

J'ai exclu un problème avec le lien symbolique (j'ai aussi essayé de déplacer le script dans le dossier bin). J'ai aussi essayé d'exécuter le script avec python

python ~/environments/project/env/bin/myscript

Auparavant, j'utilisais un script qui activait l'environnement, puis exécutait mon script, mais j'avais l'impression que le script exécuté à partir de ce dossier devrait s'exécuter avec l'interpréteur et les packages de site de virtualenv. Des idées de pourquoi cela pourrait ne pas fonctionner ou des façons dont je pourrais déboguer cela?

24
demandé sur kmonsoor 2012-08-15 05:33:49

5 réponses

Mettre le script dans le bin de votre virtualenv, puis ajouter cet emplacement bin à votre chemin global ne sera pas automatiquement source de votre virtualenv. Vous devez d'abord le sourcer pour le rendre actif.

Tout ce que votre système sait est de vérifier ce chemin supplémentaire pour l'exécutable et de l'exécuter. Il n'y a rien dans ce script indiquant un virtualenv.

Vous pouvez cependant coder en dur la ligne she-bang sur votre Python virtualenv, auquel cas les paquets de site finiront par sur le chemin:

#!/Users/foo/environments/project/env/bin/python

Ou une autre option consiste simplement à créer un petit wrapper bash qui appelle votre script pythons original, ce qui vous permettra de laisser votre script original avec un she-bang Générique..

Donc, si myscript.py est: #!/usr/bin/env python ...

, Alors vous pouvez faire un myscript :

#!/bin/bash

/Users/foo/environments/project/env/bin/python myscript.py

Lorsque vous faites myscript, Il appellera explicitement votre script python avec l'interpréteur que vous avez configuré.

40
répondu jdi 2012-08-15 02:02:34

Je pense que vous êtes confus quant à la façon dont fonctionne virtualenv.

En un mot, virtualenv modifie votre environnement shell afin que Python regarde dans différentes zones pour trouver les modules que vous souhaitez importer. Il n'y a vraiment aucune relation entre l'endroit où vous stockez votre environnement virtuel et l'endroit où vous stockez vos fichiers source que vous exécutez dans virtualenv. Si vous le souhaitez, vous pouvez stocker votre virtualenv dans un répertoire appelé ~ / environments / my_env, et toute la source que vous codez pendant utiliser votre virtualenv dans ~ / projects / my_proj.

Vous pouvez en savoir plus sur Ce Que fait virtulenv dans les documents.

Vraiment, la seule chose qui indique à python où trouver les modules est complètement basée sur python ( voir les docs sur comment cela fonctionne). L'activation d'un virtualenv change la façon dont Python fonctionne.

Vous pouvez revenir à avoir un script shell activer le virtualenv pour vous, ou vous pouvez suivre Cette recette pour l'activer directement à partir de votre script.

activate_this = '/path/to/env/bin/activate_this.py'
execfile(activate_this, dict(__file__=activate_this))

Si vous choisissez cet itinéraire, gardez à l'esprit les informations que les docs donnent:

Cela va changer sys.chemin et même changer sys.préfixe, mais aussi permettre vous pouvez utiliser un interprète existant. Articles dans votre environnement sera montrer en premier sur sys.chemin, avant les éléments globaux. Cependant, les éléments globaux sera toujours accessible (comme si l'indicateur --system-site-packages avait utilisé dans la création de l'environnement, que ce soit ou non). Également, cela ne peut pas annuler l'activation de d'autres environnements ou modules qui ont été importés. Vous ne devriez pas essayer, par exemple, activer un environnement avant une requête web, vous devez activer un environnement le plus tôt possible, et ne pas le faire à nouveau dans ce processus.

8
répondu Mark Hildreth 2012-08-15 02:00:09

Ne pourriez-vous pas simplement ajouter un chemin relatif à la place? Cela a fonctionné pour moi:

#!./env/bin/python
2
répondu Carvaka 2016-04-16 22:49:30

J'ai fait face au même problème et j'ai trouvé cette solution: https://github.com/jabbalaci/wpython . c'est un script appelé "wpython " qui appelle votre programme avec l'interpréteur Python local dans votre venv. Ainsi, au lieu de " /Users/foo/environments/project/env/bin/python myscript.py", Il suffit d'écrire "wpython /path/to/myscript.py". Un script de lancement pourrait ressembler à ceci:

#!/usr/bin/env bash

cd /the/directory/where/myscript.py/is/located
wpython myscript.py
0
répondu Jabba 2014-11-24 05:44:26

Si vous utilisez windows, vous pouvez inclure la ligne suivante en haut du fichier python.

#! P:\Workspace\pythontut\Scripts python
0
répondu user1012513 2017-01-28 14:39:10