J'ai un projet que je souhaite structurer comme ceci:
myproject
__init__.py
api
__init__.py
api.py
backend
__init__.py
backend.py
models
__init__.py
some_model.py
Maintenant, je veux importer le module some_model.py dans api.py et backend.py. Comment dois-je procéder correctement? j'ai essayé
from models import some_model
mais cela échoue avec "ModuleNotFoundError: Aucun module nommé 'models'". J'ai aussi essayé
from ..models import some_model
qui m'a ensuite donné "ValueError: tentative d'importation relative au-delà du package de niveau supérieur". Qu'est-ce que je fais mal ici? Comment puis-je importer un fichier à partir d'un répertoire différent, qui n'est pas un sous-répertoire?
Tout d'abord, cette déclaration de déclaration d'importation:
from models import some_model
doit être à espace de noms:
# in myproject/backend/backend.py or myproject/api/api.py
from myproject.models import some_model
Ensuite, vous devrez obtenir le répertoire qui contient myproject
, appelons cela /path/to/parent
, dans le sys.path
liste. Vous pouvez le faire temporairement en définissant une variable d'environnement:
export PYTHONPATH=/path/to/parent
Ou, de préférence, vous pouvez le faire en écrivant un setup.py
fichier et installation de votre package. Suivez le PyPA guide d'emballage. Après avoir écrit votre setup.py
fichier, à partir du même répertoire, exécutez-le pour configurer les entrées correctes dans sys.path
:
pip install --editable .
Malheureusement, Python ne trouvera votre fichier que si votre fichier se trouve dans le chemin du système. Mais n'ayez crainte! Il existe un moyen de contourner cela!
En utilisant le module sys
de python, nous pouvons ajouter un répertoire au chemin juste pendant que Python est en cours d'exécution, et une fois Python arrête de fonctionner, il retirez-le du chemin.
Vous pouvez le faire en:
import sys
sys.path.insert(0, '/path/to/application/app/folder')
import [file]
Il est toutefois important d'importer sys et de définir le chemin du répertoire avant d'importer le fichier.
Bonne chance!
Jordan.