python - Importieren von Dateien aus einem anderen Ordner


Ich habe die folgende Ordnerstruktur.

application/app/folder/file.py

und ich möchte einige Funktionen von 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?



Answers



Standardmäßig können Sie nicht. Beim Importieren einer Datei durchsucht Python nur das aktuelle Verzeichnis, das Verzeichnis, aus dem das Einstiegspunkt-Skript ausgeführt wird, und sys.path das Speicherorte wie das Installationsverzeichnis des Pakets enthält (es ist eigentlich etwas komplexer als das, aber dies deckt meiste Fälle).

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

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

import file



Nichts falsch mit:

from application.app.folder.file import func_name

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




Wenn Module parallel sind, wie in der Frage:

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

Diese Abkürzung macht ein Modul für den anderen sichtbar:

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



Da Ihre Frage * nix-spezifisch aussieht, denke ich, wäre ein sauberer Weg, die Umgebungsvariable zu verwenden

PYTHONPATH

wie in der Dokumentation beschrieben: Python2 , Python3

export PYTHONPATH=$HOME/dirWithScripts/:$PYTHONPATH



Von dem, was ich weiß, fügen Sie eine __init__.py Datei direkt in den Ordner der Funktionen, die Sie importieren möchten, um den Auftrag __init__.py .




Arbeitete für mich in Python3 unter Linux

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



Wenn Sie die application als Stammverzeichnis für Ihr Python-Projekt in Betracht ziehen, erstellen Sie eine leere __init__.py Datei in application , __init__.py und __init__.py . some_file.py dann in Ihrer some_file.py die folgenden Änderungen vor, 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()



Das funktioniert für mich bei Windows

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

import some_file



Wenn Sie ein Modul aus einem bestimmten Pfad laden möchten, um Sie bei der Entwicklung eines benutzerdefinierten Moduls zu unterstützen, können Sie einen symbolischen Link im selben Ordner des Testskripts erstellen, der auf das Stammverzeichnis des benutzerdefinierten Moduls verweist. Diese Modulreferenz hat Vorrang vor allen anderen Modulen, die für ein Skript in diesem Ordner mit demselben Namen installiert wurden.

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

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




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 das Python-Verzeichnis.

Dazu ändern Sie dies:

from application.app.folder.file import func_name

dazu:

from .application.app.folder.file import func_name

Indem Sie den Punkt hinzufügen, den Sie sagen, suchen Sie in diesem Ordner nach dem Anwendungsordner, statt in das Python-Verzeichnis zu schauen.

(Hoffe das behebt dein Problem!)




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

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

Und bei Verwendung von Windows können \ und / als Trennzeichen für Dateinamen verwendet werden und natürlich müssen Sie in Python-Zeichenketten 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-native' ist, weil es Linux-kompatibel ist und einfacher zu schreiben und in Windows-Explorer zu kopieren)




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 ausgeführt wird.

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

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

Angenommen, Sie möchten das Modul "Mango" importieren. In Vanilla.py könnten Sie 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 benötigen Sie die Variable mango_dir nicht.

Um zu verstehen, wie dies funktioniert, schauen Sie sich dieses interaktive Sitzungsbeispiel 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.




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




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