137 votes

Importation du module à partir du sous-dossier

Je veux importer des sous-dossiers en tant que modules. Par conséquent, chaque sous-dossier contient un __init__.py . La structure de mes dossiers est la suivante :

src\
  main.py
  dirFoo\
    __init__.py
    foofactory.py
    dirFoo1\
      __init__.py
      foo1.py
    dirFoo2\
      __init__.py
      foo2.py

Dans mon script principal, j'importe

from dirFoo.foofactory import FooFactory

Dans ce fichier d'usine, j'inclus les sous-modules :

from dirFoo1.foo1 import Foo1
from dirFoo2.foo2 import Foo2

Si j'appelle mon foofactory, j'obtiens l'erreur suivante : python ne peut pas importer les submodules foo1 et foo2 :

Traceback (most recent call last):
  File "/Users/tmp/src/main.py", line 1, in <module>
from dirFoo.foofactory import FooFactory
  File "/Users/tmp/src/dirFoo/foofactory.py", line 1, in    <module>
from dirFoo1.foo1 import Foo1
    ImportError: No module named dirFoo1.foo1

176voto

Rob Wouters Points 6654

Il n'y a pas besoin d'embrouiller votre PYTHONPATH o sys.path ici.

Pour utiliser correctement les importations absolues dans un paquet, vous devez également inclure le nom du paquet "Root", par exemple :

from dirFoo.dirFoo1.foo1 import Foo1
from dirFoo.dirFoo2.foo2 import Foo2

Ou vous pouvez utiliser importations relatives :

from .dirfoo1.foo1 import Foo1
from .dirfoo2.foo2 import Foo2

61 votes

Une chose à retenir ! ajouter __init__.py à chaque sous-dossier à partir duquel vous effectuez l'importation.

9 votes

Vide __init__.py peut faire l'affaire.

2 votes

Quelle serait la syntaxe si précédemment Foo1 était dans le répertoire parent et on codait quelque chose comme from Foo1 import * . Existe-t-il un moyen d'obtenir le même effet sans avoir à tout préfixer avec le symbole Foo1 ?

29voto

Vivek22 Points 349

Juste pour notifier ici. (de la part d'un newbee, keviv22)

Pour votre bien, ne nommez jamais et jamais les dossiers ou les fichiers avec des symboles comme "-" ou "_". Si vous le faites, vous risquez d'être confronté à quelques problèmes. Comme le mien, disons que, bien que votre commande d'importation soit correcte, vous ne pourrez pas importer avec succès les fichiers désirés qui sont disponibles dans ces dossiers nommés.

Noms de dossiers non valides comme suit :

  • Dossier des classes génériques
  • Dossier des classes génériques

Noms de dossiers valables pour le ci-dessus :

  • GenericClassesFolder ou Genericclassesfolder ou genericClassesFolder (ou comme ceci, sans espace ni symbole spécial entre les mots)

Quelle erreur j'ai faite :

tenir compte de la structure du fichier.

Parent
   . __init__.py
   . Setup
     .. __init__.py
     .. Generic-Class-Folder
        ... __init__.py
        ... targetClass.py
   . Check
     .. __init__.py
     .. testFile.py

Ce que je voulais faire ?

  • à partir de testFile.py, je voulais importer le fichier 'targetClass.py' dans le fichier Generic-Class-Folder pour utiliser la fonction nommée "functionExecute" dans le fichier 'targetClass.py'.

Quel commandement j'ai fait ?

  • de 'testFile.py', a écrit la commande, from Core.Generic-Class-Folder.targetClass import functionExecute
  • J'ai eu des erreurs comme SyntaxError: invalid syntax

J'ai essayé de nombreuses recherches et j'ai consulté de nombreuses questions sur stackoverflow, mais je n'arrive pas à trouver ce qui ne va pas. J'ai recoupé mes fichiers plusieurs fois, j'ai utilisé __init__.py fichier, inséré chemin de l'environnement et inquiet de ce qui a mal tourné......

Et après un long long long long temps, j'ai compris ça en parlant avec un de mes amis. Je suis un peu stupide pour utiliser de telles conventions de nommage. Je ne devrais jamais utiliser d'espace ou de symboles spéciaux pour définir le nom d'un dossier ou d'un fichier. C'est donc ce que je voulais dire. Passez une bonne journée !

(désolé pour l'énorme post sur ce sujet... je laisse juste sortir mes frustrations.... :) Merci !)

10voto

Maxim Kamenkov Points 111

Définissez votre variable d'environnement PYTHONPATH. Par exemple comme ceci PYTHONPATH=. : (pour la famille *nix).

Vous pouvez également ajouter manuellement votre répertoire actuel (src dans votre cas) à pythonpath :

import os
import sys
sys.path.insert(0, os.getcwd())

7voto

fwuensche Points 923

Disons que votre projet est structuré de cette façon :

+---MyPythonProject
|   +---.gitignore
|   +---run.py
|   |   +---subscripts
|   |   |   +---script_one.py
|   |   |   +---script_two.py

À l'intérieur de run.py vous pouvez importer les scripts 1 et 2 en.. :

from subscripts import script_one as One
from subscripts import script_two as Two

Maintenant, toujours à l'intérieur run.py vous pourrez appeler leurs méthodes avec :

One.method_from_one(param)
Two.method_from_two(other_param)

2voto

Il suffit de créer un __init__.py et ajoutez-le dans le répertoire racine ainsi que dans tous les sous-répertoires/dossiers de votre application python où vous avez d'autres modules python. Voir https://docs.python.org/3/tutorial/modules.html#packages

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