Impossible d'importer mes propres modules en Python


141

J'ai du mal à comprendre comment l'importation de modules fonctionne en Python (je ne l'ai jamais fait dans aucun autre langage avant non plus).

Disons que j'ai:

myapp/__init__.py
myapp/myapp/myapp.py
myapp/myapp/SomeObject.py
myapp/tests/TestCase.py

Maintenant, j'essaye d'obtenir quelque chose comme ça:

myapp.py
===================
from myapp import SomeObject
# stuff ...

TestCase.py
===================
from myapp import SomeObject
# some tests on SomeObject

Cependant, je fais définitivement quelque chose de mal car Python ne peut pas voir qu'il myapps'agit d'un module:

ImportError: No module named myapp

Réponses:


96

Dans votre cas particulier, il semble que vous essayez d'importer à SomeObjectpartir des scripts myapp.py et TestCase.py. Depuis myapp.py, faites

import SomeObject

car il est dans le même dossier. Pour TestCase.py, faites

from ..myapp import SomeObject

Cependant , cela ne fonctionnera que si vous importez TestCase à partir du package. Si vous voulez exécuter directement python TestCase.py, vous devrez jouer avec votre chemin. Cela peut être fait dans Python:

import sys
sys.path.append("..")
from myapp import SomeObject

bien que ce ne soit généralement pas recommandé.

En général, si vous souhaitez que d'autres personnes utilisent votre package Python, vous devez utiliser distutils pour créer un script de configuration. De cette façon, n'importe qui peut installer votre paquet facilement en utilisant une commande comme python setup.py installet il sera disponible partout sur sa machine. Si vous êtes sérieux au sujet du package, vous pouvez même l'ajouter à l'index du package Python, PyPI .


J'ai essayé d'utiliser simplement importdans mon TestCase.pymais cela m'a toujours donné la même erreur. Je suppose que c'est parce que c'est dans un sous-répertoire du __init__.py?
n0pe

Oh attendez, je pense que je comprends. Si mes scénarios de test appellent à partir du package, je pourrai utiliser le from ... import ...droit?
n0pe

1
Vous ne le ferez que si TestCase est importé de l'extérieur du package - par exemple, si j'exécute from myapp.tests import TestCase from a script outside myapp. If you're running python TestCase.py` dans le dossier de tests, vous ne pouvez pas effectuer d'importations relatives
David Robinson

1
J'ai exécuté "pip install -e." Pour installer myapp, mais en essayant d'exécuter TestCase dans le code de Visual Studio, j'obtiens toujours "ImportError: Aucun module nommé myapp". mais si je lance "python", puis en python, je lance "à partir de myapp import SomeObject", cela fonctionne. Qu'est-ce que je fais mal?
dagrun

@DavidRobinson J'ai utilisé la méthode que vous avez mentionnée, qui n'a montré aucune erreur après l'exécution from fodername import file_name_of_my_py_code, mais lorsque j'ai essayé d'accéder à l'objet défini, file_name_of_my_py_code.pyelle ditNameError: name 'ClassName' is not defined
Kavin Raju S

44

La fonction importrecherche des fichiers dans votre env PYTHONPATH. variable et votre répertoire local. Vous pouvez donc soit mettre tous vos fichiers dans le même répertoire, soit exporter le chemin en tapant dans un terminal:

export PYTHONPATH="$PYTHONPATH:/path_to_myapp/myapp/myapp/"

2
Alors, comment puis-je m'assurer que cela fonctionne pour tous les autres qui l'utilisent? Je préfère ne pas avoir à leur dire de définir certaines variables d'environnement avant de l'exécuter.
n0pe

1
le répertoire courant est dans pythonpath, donc tant que les scripts sont dans le même dossier / répertoire, cela devrait fonctionner. malheureusement, chacun de ces scripts se trouve dans des répertoires séparés.
JKirchartz

4
Pour les utilisateurs de Windows, au lieu de exportnous avons "set PYTHONPATH =% PYTHONPATH%; C: \ path_to_myapp \ myapp \ myapp \"
aimé.by.Jesus

Dans vs code, j'ai pu résoudre ce problème en ajoutant la variable PYTHONPATH Env à mon launch.json: "env": {"PYTHONPATH": "$ {workspaceFolder}"}
Michael Armitage

11

le chemin d'exportation est un bon moyen. Une autre façon consiste à ajouter un .pth à l'emplacement de vos packages de site. Sur mon mac, mon python conserve les packages de site dans / Library / Python ci-dessous

/Library/Python/2.7/site-packages

J'ai créé un fichier appelé awesome.pth dans /Library/Python/2.7/site-packages/awesome.pth et dans le fichier, mettez le chemin suivant qui fait référence à mes super modules

/opt/awesome/custom_python_modules

1
dans le cas où je travaille sous Windows, comment faire
Nwawel A Iroume

Je ne suis pas sûr. Dans le cas où vous utilisez Windows. Trouvez des logiciels vm et utilisez Linux. Ou - voir cette réponse sur l'exportation de variables dans Windows. stackoverflow.com/questions/559816/…
jmontross

c'est exactement ce dont j'avais besoin
Lee88

1
Heureux d'entendre ça @ Lee88 - m'a pris du temps pour le découvrir moi-même :)
jmontross

9

Tu peux essayer

from myapp.myapp import SomeObject

car le nom de votre projet est le même que myapp.py, ce qui lui permet de rechercher d'abord le document de projet


3

Dans votre premier répertoire myapp, vous pouvez ajouter un fichier setup.py et ajouter deux codes python dans setup.py

from setuptools import setup
setup(name='myapp')

dans votre premier répertoire myapp en ligne de commande, utilisez pip install -e. pour installer le package


2

pip installsur Windows 10, l'installation par défaut dans 'Program Files / PythonXX / Lib / site-packages' qui est un répertoire qui nécessite des privilèges administratifs. J'ai donc résolu mon problème en exécutant pip install en tant qu'administrateur (vous devez ouvrir l'invite de commande en tant qu'administrateur même si vous êtes connecté avec un compte administrateur). De plus, il est plus sûr d'appeler pip depuis python.
par exemple
python -m pip install <package-name>
au lieu de
pip install <package-name>


0

Dans mon cas, c'était une surprise Windows vs Python, bien que les noms de fichiers Windows ne soient pas sensibles à la casse, l'importation Python l'est. Donc, si vous avez un Stuff.pyfichier, vous devez importer ce nom tel quel.


0

Vous devez avoir

__init__.py

dans tous les dossiers contenant du code avec lequel vous devez interagir. Vous devez également spécifier le nom du dossier supérieur de votre projet à chaque importation, même si le fichier que vous avez essayé d'importer est au même niveau.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.