Modul aus Unterordner importieren

104

Ich möchte Unterordner als Module importieren. Daher enthält jeder Unterordner a __init__.py. Meine Ordnerstruktur sieht folgendermaßen aus:

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

In meinem Hauptskript importiere ich

from dirFoo.foofactory import FooFactory

In dieser Factory-Datei füge ich die Untermodule hinzu:

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

Wenn ich meine foofactory aufrufe, erhalte ich die Fehlermeldung, dass Python die Submodule foo1 und foo2 nicht importieren kann:

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
Rasierer
quelle

Antworten:

136

Sie müssen sich nicht mit Ihrem PYTHONPATHoder sys.pathhier anlegen .

Um absolute Importe in einem Paket richtig zu verwenden, sollten Sie auch den Paketnamen "root" angeben, z.

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

Oder Sie können relative Importe verwenden :

from .dirfoo1.foo1 import Foo1
from .dirfoo2.foo2 import Foo2
Rob Wouters
quelle
47
Eine Sache, an die man sich erinnern sollte! hinzufügen __init__.pyzu jedem Unterordner Sie importieren.
Aziz Alto
6
Leer __init__.pykann den Job machen.
Cerebrou
1
Was wäre die Syntax , wenn zuvor Foo1im Verzeichnis Eltern war und ein codiertes so etwas wie from Foo1 import *. Gibt es eine Möglichkeit, denselben Effekt zu erzielen, damit Sie nicht alles voranstellen müssen Foo1?
Jxramos
1
@ AzizAlto: Ohne Ihren Kommentar ist diese Lösung nicht sehr nützlich
Alex
21

Nur um hier zu benachrichtigen. (von einem Newbee, keviv22)

Benennen Sie die Ordner oder Dateien niemals zu Ihrem eigenen Wohl mit Symbolen wie "-" oder "_". Wenn Sie dies getan haben, können einige Probleme auftreten. Wie bei mir, obwohl Ihr Befehl zum Importieren korrekt ist, können Sie die gewünschten Dateien, die in solchen benannten Ordnern verfügbar sind, nicht erfolgreich importieren.

Ungültige Ordnernamen wie folgt:

  • Generic-Classes-Folder
  • Generic_Classes_Folder

gültige Ordnernamen für oben:

  • GenericClassesFolder oder Genericclassesfolder oder genericClassesFolder (oder so ohne Leerzeichen oder spezielle Symbole zwischen den Wörtern)

Welchen Fehler habe ich gemacht:

Betrachten Sie die Dateistruktur.

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

Was wollte ich machen

  • Aus testFile.py wollte ich die Datei 'targetClass.py' in die Datei Generic-Class-Folder importieren, um die Funktion "functionExecute" in der Datei 'targetClass.py' zu verwenden

Welchen Befehl habe ich getan?

  • aus 'testFile.py', Befehl geschrieben, from Core.Generic-Class-Folder.targetClass import functionExecute
  • Habe Fehler wie SyntaxError: invalid syntax

Versuchte viele Suchanfragen und sah viele Fragen zum Stapelüberlauf an und konnte nicht entscheiden, was schief gelaufen ist. Ich habe meine Dateien mehrmals überprüft, Dateien verwendet __init__.py, den Umgebungspfad eingefügt und mir große Sorgen darüber gemacht, was schief gelaufen ist.

Und nach einer langen, langen, langen Zeit habe ich das herausgefunden, als ich mit einem Freund von mir gesprochen habe. Ich bin ein bisschen dumm, solche Namenskonventionen zu verwenden. Ich sollte niemals Leerzeichen oder spezielle Symbole verwenden, um einen Namen für einen Ordner oder eine Datei zu definieren. Das wollte ich also vermitteln. Haben Sie einen guten Tag!

(Entschuldigung für den riesigen Beitrag darüber ... lass einfach meine Frustrationen los ... :) Danke!)

Vivek22
quelle
22
Leerzeichen und Bindestriche ("-") würden dies verursachen, aber Unterstriche ("_") sollten weiterhin einwandfrei funktionieren.
Cowlinator
6

Legen Sie Ihre Umgebungsvariable PYTHONPATH fest. Zum Beispiel so PYTHONPATH = .: .. (für * nix Familie).

Sie können Ihr aktuelles Verzeichnis (in Ihrem Fall src) auch manuell zu pythonpath hinzufügen:

import os
import sys
sys.path.insert(0, os.getcwd())
Max Kamenkov
quelle
2

Angenommen, Ihr Projekt ist folgendermaßen strukturiert:

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

Im Inneren run.pykönnen Sie die Skripte eins und zwei importieren, indem Sie:

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

Jetzt, noch drinnen run.py, können Sie ihre Methoden aufrufen mit:

One.method_from_one(param)
Two.method_from_two(other_param)
Flavio Wuensche
quelle
1

Erstellen Sie einfach eine leere ___init____.py-Datei und fügen Sie sie im Stammverzeichnis sowie im gesamten Unterverzeichnis / Ordner Ihrer Python-Anwendung hinzu, in dem Sie andere Python-Module haben.

Abhijit Pritam Dutta
quelle
-2

Hatte Probleme, selbst wenn init .py im Unterordner vorhanden war und alles, was fehlte, war das Hinzufügen von 'as' nach dem Import

from folder.file import Class as Class
import folder.file as functions
Tomas Trdla
quelle