Importieren von Dateien aus einem anderen Ordner

Ich habe folgende Ordnerstruktur.

application/app/folder/file.py

und ich möchte einige functionen aus file.py in eine andere Python – Datei importieren, die sich in

application/app2/some_folder/some_file.py

ich habe es versucht

from application.app.folder.file import func_name

und einige andere verschiedene Versuche, aber bis jetzt konnte ich nicht richtig importieren. Wie kann ich das machen?

    Standardmäßig können Sie nicht. Beim Importieren einer Datei durchsucht Python nur das aktuelle Verzeichnis, das Verzeichnis, aus dem das Einstiegspunktskript ausgeführt wird, und sys.path das Speicherorte wie das sys.path enthält (es ist tatsächlich ein wenig komplexer als dies, aber dies deckt sys.path meiste Fälle).

    Sie können jedoch zur Laufzeit dem Python-Pfad hinzufügen:

     # some_file.py import sys sys.path.insert(0, '/path/to/application/app/folder') import file 

    Nichts ist falsch mit:

     from application.app.folder.file import func_name 

    Stellen Sie nur sicher, dass der Ordner auch ein __init__.py enthält, damit es als Paket eingebunden werden kann. Nicht sicher, warum die anderen Antworten über PYTHONPATH sprechen.

    Wenn Module an parallelen Orten sind, wie in der Frage:

     application/app2/some_folder/some_file.py application/app2/another_folder/another_file.py 

    Diese Kurzschrift macht ein Modul für das andere sichtbar:

     import sys sys.path.append('../') 

    Ich denke, ein sauberer Weg wäre, die Umgebungsvariable PYTHONPATH wie in der Dokumentation beschrieben: Python2 , Python3

     export PYTHONPATH=$HOME/dirWithScripts/:$PYTHONPATH # Windows users: use "set" instead of "export" 

    Von dem, was ich weiß, fügen Sie eine __init__.py Datei direkt in den Ordner der functionen, die Sie importieren möchten, wird die Aufgabe erledigen.

    Wenn Sie die application als Stammverzeichnis für Ihr Python-Projekt betrachten, erstellen Sie eine leere Datei __init__.py in den application , application und __init__.py . Dann some_file.py in deiner some_file.py wie folgt aus, um die Definition von func_name zu erhalten:

     import sys sys.path.insert(0, r'/from/root/directory/application') from application.app.folder.file import func_name ## You can also use '*' wildcard to import all the functions in file.py file. func_name() 

    Die Antworten hier sind nicht klar genug, dies wird auf Python 3.6 getestet

    Mit dieser Ordnerstruktur:

     main.py | ---- myfolder/myfile.py 

    Wo myfile.py den Inhalt hat:

     def myfunc(): print('hello') 

    Die Importanweisung in main.py lautet:

     from myfolder.myfile import myfunc myfunc() 

    und das wird Hallo drucken.

    Arbeitete für mich in Python3 unter Linux

     import sys sys.path.append(pathToFolderContainingScripts) from scriptName import functionName #scriptName without .py extension 

    Ihr Problem ist, dass Python im Python-Verzeichnis nach dieser Datei sucht und sie nicht findet. Sie müssen angeben, dass Sie über das Verzeichnis sprechen, in dem Sie sich befinden, und nicht über das Python-Verzeichnis.

    Um dies zu tun, ändern Sie dies:

    from application.app.folder.file import func_name

    zu diesem:

     from .application.app.folder.file import func_name 

    Fügen Sie den Punkt hinzu, den Sie sagen, suchen Sie in diesem Ordner nach dem Anwendungsordner, anstatt im Python-Verzeichnis zu suchen.

    Das funktioniert bei mir unter Windows

     # some_file.py on mainApp/app2 import sys sys.path.insert(0, sys.path[0]+'\\app2') import some_file 

    Erster Import sys

      import sys 

    Zweiter Anhang den Ordnerpfad

     sys.path.insert(0, '/the/folder/path/name-folder/') 

    3. Erstellen Sie eine leere Datei namens __ init __.py in Ihrem Unterverzeichnis (dies teilt Python mit, dass es sich um ein Modul handelt).

    • Name-Datei.py
      • Name-Ordner
        • __ init __.py
        • name-module.py

    Viertens importieren Sie das Modul in den Ordner

     from name-folder import name-module 

    Versuche Pythons relative Importe:

     from ...app.folder.file import func_name 

    Jeder führende Punkt ist eine andere höhere Ebene in der Hierarchie, beginnend mit dem aktuellen Verzeichnis.


    Probleme? Wenn dies nicht für Sie funktioniert, dann werden Sie wahrscheinlich durch die vielen Import-Import-Importerrors etwas bekommen. Lesen Sie Antworten und Kommentare für weitere Details: Wie behebt man “Versuch eines relativen Imports in Nicht-Paket” sogar mit __init__.py

    Hinweis: Haben Sie __init__.py auf jeder Verzeichnisebene. Sie benötigen möglicherweise python -m application.app2.some_folder.some_file (von .py weglassen), die Sie aus dem Verzeichnis der obersten Ebene ausführen, oder dieses oberste Verzeichnis in Ihrem PYTHONPATH haben. Puh!

    Die Verwendung von sys.path.append mit einem absoluten Pfad ist nicht ideal, wenn die Anwendung in andere Umgebungen verschoben wird. Die Verwendung eines relativen Pfads funktioniert nicht immer, da das aktuelle Arbeitsverzeichnis davon abhängt, wie das Skript aufgerufen wurde.

    Da die Anwendungsordnerstruktur fest ist, können wir os.path verwenden, um den vollständigen Pfad des Moduls zu erhalten, das wir importieren möchten. Zum Beispiel, wenn dies die Struktur ist:

     /home/me/application/app2/some_folder/vanilla.py /home/me/application/app2/another_folder/mango.py 

    Nehmen wir an, Sie möchten das Modul “Mango” importieren. Sie können in vanilla.py Folgendes tun:

     import sys, os.path mango_dir = (os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) + '/another_folder/') sys.path.append(mango_dir) import mango 

    Natürlich brauchen Sie die Variable mango_dir nicht.

    Um zu verstehen, wie dies funktioniert, sehen Sie sich dieses interaktive Beispiel an:

     >>> import os >>> mydir = '/home/me/application/app2/some_folder' >>> newdir = os.path.abspath(os.path.join(mydir, '..')) >>> newdir '/home/me/application/app2' >>> newdir = os.path.abspath(os.path.join(mydir, '..')) + '/another_folder' >>> >>> newdir '/home/me/application/app2/another_folder' >>> 

    Und überprüfen Sie die os.path- Dokumentation.

    Wenn der Zweck des Ladens eines Moduls aus einem bestimmten Pfad darin besteht, Sie bei der Entwicklung eines benutzerdefinierten Moduls zu unterstützen, können Sie einen symbolischen Link in demselben Ordner des Testskripts erstellen, der auf das Stammverzeichnis des benutzerdefinierten Moduls verweist. Diese Modulreferenz hat Vorrang vor allen anderen installierten Modulen mit demselben Namen für jedes Skript, das in diesem Ordner ausgeführt wird.

    Ich habe das unter Linux getestet, aber es sollte in jedem modernen Betriebssystem funktionieren, das symbolische Links unterstützt.

    Ein Vorteil dieses Ansatzes besteht darin, dass Sie auf ein Modul verweisen können, das in Ihrer eigenen lokalen SVC-Zweigarbeitskopie sitzt, was die Entwicklungszykluszeit erheblich vereinfachen und Fehlermodi beim Verwalten verschiedener Versionen des Moduls reduzieren kann.

    Ich bin etwas ganz Besonderes: Ich benutze Python mit Windows!

    Ich vervollständige nur die Information: sowohl für Windows als auch für Linux arbeiten sowohl der relative als auch der absolute Pfad in sys.path (ich brauche relative Pfade, weil ich meine Skripte auf den verschiedenen PCs und unter verschiedenen Hauptverzeichnissen verwende).

    Und bei der Verwendung von Windows können sowohl \ als auch / als Trennzeichen für Dateinamen verwendet werden und natürlich müssen Sie \ in Python-Zeichenfolgen doppelklicken.
    einige gültige Beispiele:

     sys.path.append('c:\\tools\\mydir') sys.path.append('..\\mytools') sys.path.append('c:/tools/mydir') sys.path.append('../mytools') 

    (Hinweis: Ich denke, dass / ist bequemer als \ , Ereignis, wenn es weniger ‘Windows-nativ’ ist, weil es Linux-kompatibel ist und einfacher zu schreiben und in Windows Explorer kopieren)

    Also hatte ich gerade richtig auf meine IDE geklickt und einen neuen folder hinzugefügt und mich gefragt, warum ich nicht importieren konnte. Später wurde mir klar, dass ich mit der rechten Maustaste klicken und ein Python-Paket erstellen muss, und keinen klassischen Dateisystemordner. Oder eine Post-Mortem-Methode, die ein __init__.py hinzufügt (wodurch python den Dateisystemordner als Paket behandelt), wie in anderen Antworten erwähnt. Diese Antwort hier hinzufügen für den Fall, dass jemand diesen Weg gegangen ist.

    Sie können die Python-Shell aktualisieren, indem Sie f5 drücken oder zu Run-> Run Module gehen. Auf diese Weise müssen Sie das Verzeichnis nicht ändern, um etwas aus der Datei zu lesen. Python wird das Verzeichnis automatisch ändern. Wenn Sie jedoch mit verschiedenen Dateien aus einem anderen Verzeichnis in der Python-Shell arbeiten möchten, können Sie das Verzeichnis in sys ändern, wie Cameron bereits sagte .

    In meinem Fall musste ich eine class importieren. Meine Datei sah folgendermaßen aus:

     # /opt/path/to/code/log_helper.py class LogHelper: # stuff here 

    In meiner Hauptdatei habe ich den Code eingefügt über:

     path.append("/opt/path/to/code/") from log_helper import LogHelper 

    In Python 3.4 und höher können Sie direkt aus einer Quelldatei importieren (Link zur Dokumentation) .

    Hier ist ein Beispiel. Zuerst die zu importierende Datei namens foo.py :

     def announce(): print("Imported!") 

    Der Code, der die obige Datei importiert, ist stark vom Beispiel in der Dokumentation inspiriert:

     import importlib, importlib.util, os.path def module_from_file(module_name, file_path): spec = importlib.util.spec_from_file_location(module_name, file_path) module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) return module foo = module_from_file("foo", "/path/to/foo.py") if __name__ == "__main__": print(foo) print(dir(foo)) foo.announce() 

    Die Ausgabe:

      ['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'announce'] Imported! 

    Beachten Sie, dass der Variablenname, der Modulname und der Dateiname nicht übereinstimmen müssen. Dieser Code funktioniert immer noch:

     import importlib, importlib.util, os.path def module_from_file(module_name, file_path): spec = importlib.util.spec_from_file_location(module_name, file_path) module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) return module baz = module_from_file("bar", "/path/to/foo.py") if __name__ == "__main__": print(baz) print(dir(baz)) baz.announce() 

    Die Ausgabe:

      ['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'announce'] Imported! 

    Programmgesteuertes Importieren von Modulen wurde in Python 3.1 eingeführt und gibt Ihnen mehr Kontrolle darüber, wie Module importiert werden. Weitere Informationen finden Sie in der Dokumentation.

     sys.path.insert(0, '/path/to/application/app/folder')