87 votes

Importation de script depuis un répertoire parent

Comment importer un module (fichier python) qui réside dans le répertoire parent ?

Les deux répertoires ont un __init__.py mais je ne peux toujours pas importer un fichier depuis le répertoire parent ?

Dans cette disposition de dossier, script B tente d'importer script A :

Folder A:
   __init__.py
   Script A:
   Folder B:
     __init__.py
     Script B(attempting to import Script A)

Le code suivant dans script B ne fonctionne pas :

import ../scriptA.py # I get a compile error saying the "." is invalid

0 votes

Je ne réponds pas exactement à votre question, mais si vous exécutez init .py à l'intérieur du dossier A et essayer d'importer le dossier B ou script B, script A sera importé avec succès à l'intérieur de script B.

0 votes

81voto

J.F. Sebastian Points 102961

On n'importe pas des scripts en Python, mais des modules. Certains modules Python sont également des scripts que vous pouvez exécuter directement (ils effectuent un travail utile au niveau du module).

En général, il est préférable d'utiliser des importations absolues plutôt que des importations relatives.

toplevel_package/
 __init__.py
 moduleA.py
 subpackage
     __init__.py
     moduleB.py

Sur moduleB :

from toplevel_package import moduleA

Si vous souhaitez vous présenter moduleB.py comme un script alors assurez-vous que le répertoire parent pour toplevel_package est dans votre sys.path .

12 votes

Et pourquoi les "hacks" de sys path ne pourraient-ils pas être utilisés dans ce cas ? Python rend si difficile de faire ce que vous voulez ici sans eux. Quel est exactement l'inconvénient ici ?

4 votes

@BT _" sys.path.append(path_to_parent) " ne devrait pas être une réponse à comment réparer ""import ../scriptA.py # J'obtiens une erreur de compilation disant que le "." n'est pas valide""_ question. Il y a des cas où changer sys.path pourrait être utile, par exemple, si python lui-même l'avait fait ou si un module tripartite qui gère correctement tous les cas de figure l'avait fait, par exemple, import autopath; autopath.add_toplevel_to_syspath() qui ajoute automatiquement le répertoire parent de toplevel_package à sys.path pour permettre l'exécution directe d'un module interne en tant que script (ou dans un REPL) depuis n'importe quel répertoire sans PYTHONPATH ou (virtualenv) install approprié.

3 votes

@J.F.Sebastian Y a-t-il une sorte de proposition pour une fonctionnalité qui nous permette de dire explicitement quel est le dossier ou le paquet principal de l'ensemble du projet, de sorte que nous n'ayons pas à nous soucier d'ajouter des répertoires parents à sys.path afin que nous puissions exécuter des submodules également en tant que fichiers principaux ou scripts ? J'ai un projet où j'ai vraiment besoin d'exécuter scripts à la fois comme principaux ou comme modules, c'est importé, mais je dois faire des tonnes de hacks en ajoutant des chemins à sys.path pour les faire fonctionner dans les deux cas. Est-ce que le travail dans un virtualenv ou l'utilisation de setuptools fonctionnerait d'une manière ou d'une autre ? J'ai vraiment du mal avec ça...

36voto

Rob Wouters Points 6654

De la docs :

from .. import scriptA

Vous pouvez le faire dans les paquets, mais pas dans les scripts que vous exécutez directement. À partir du lien ci-dessus :

Notez que les importations relatives explicites et implicites sont basées sur le nom du module actuel. nom du module courant. Puisque le nom du module principal est toujours "__main__", les modules destinés à être utilisés comme module principal d'une application application Python doivent toujours utiliser des importations absolues.

Si vous créez un script qui importe A.B.B, vous ne recevrez pas le ValueError.

30 votes

ValueError : Tentative d'importation relative dans un non-paquet

3 votes

@jgritty, c'est parce que vous le faites dans un script que vous exécutez directement.

2 votes

Oui, vous avez raison. Cela fonctionnera si vous appelez un script qui importe ensuite le script B.

6voto

capfredf Points 387

Si vous voulez exécuter le script directement, vous pouvez le faire :

  1. Ajoutez le chemin du DossierA à la variable d'environnement ( PYTHONPATH ).
  2. Ajouter le chemin vers sys.path dans votre script.

Ensuite :

import module_you_wanted

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X