Ich codiere mod1und ich muss etwas aus importieren mod2. Wie soll ich es machen?
Ich habe es versucht from ..sub2 import mod2aber ich erhalte die Meldung “Attempted relative import in non-package”.
Ich habe herumgegoogelt, aber ich fand nur “sys.path Manipulation”-Hacks. Gibt es keinen sauberen Weg?
Alle meine __init__.pysind derzeit leer
Ich versuche dies, weil sub2 Klassen enthält, die von Unterpaketen gemeinsam genutzt werden (sub1, subXusw.).
Das Verhalten, nach dem ich suche, ist das gleiche wie in beschrieben PEP 366 (danke John B).
Ich empfehle, Ihre Frage zu aktualisieren, um deutlicher zu machen, dass Sie das in PEP 366 behandelte Problem beschreiben.
– Johannes B
16. September 2008 um 19:36 Uhr
Es ist eine langwierige Erklärung, aber überprüfen Sie hier: stackoverflow.com/a/10713254/1267156 Ich habe eine sehr ähnliche Frage beantwortet. Ich hatte das gleiche Problem bis gestern Abend.
– Sevvy325
23. Mai 2012 um 4:05 Uhr
Für diejenigen, die ein Modul laden möchten, das sich in einem beliebigen Pfad befindet, siehe hier: stackoverflow.com/questions/67631/…
– Jewgeni Sergejew
8. Juni 2014 um 6:29 Uhr
In diesem Zusammenhang wird Python 3 die Standardbehandlung von Importen so ändern, dass sie standardmäßig absolut ist. relative Importe müssen explizit angegeben werden.
– Roß
30. März 2015 um 23:28 Uhr
Johannes B
Das Problem besteht darin, dass Sie das Modul als „__main__“ ausführen, indem Sie mod1.py als Argument an den Interpreter übergeben.
Relative Importe verwenden das __name__-Attribut eines Moduls, um die Position dieses Moduls in der Pakethierarchie zu bestimmen. Wenn der Name des Moduls keine Paketinformationen enthält (z. B. auf „__main__“ gesetzt ist), werden relative Importe so aufgelöst, als ob das Modul ein Modul der obersten Ebene wäre, unabhängig davon, wo sich das Modul tatsächlich im Dateisystem befindet.
In Python 2.6 fügen sie die Möglichkeit hinzu, Module relativ zum Hauptmodul zu referenzieren. PEP 366 beschreibt die Veränderung.
Laut Nick Coghlan besteht die empfohlene Alternative darin, das Modul innerhalb des Pakets mit dem Schalter -m auszuführen.
Die empfohlene Alternative besteht darin, Module innerhalb von Paketen mit dem auszuführen -m wechseln, anstatt ihren Dateinamen direkt anzugeben.
– ncoghlan
23. Februar 2011 um 4:25 Uhr
Ich verstehe nicht: Wo ist hier die Antwort? Wie kann man Module in eine solche Verzeichnisstruktur importieren?
– Tom
29. September 2012 um 16:34 Uhr
@Tom: In diesem Fall wäre mod1 from sub2 import mod2. Führen Sie dann mod1 aus der App aus aus python -m sub1.mod1.
– Xiong Tschamiow
20. November 2012 um 6:06 Uhr
@XiongChiamiov: Bedeutet dies, dass Sie dies nicht tun können, wenn Ihr Python in eine Anwendung eingebettet ist, sodass Sie keinen Zugriff auf Python-Befehlszeilenschalter haben?
– LarsH
29. Januar 2013 um 16:58 Uhr
„Jeder scheint Ihnen sagen zu wollen, was Sie tun sollen, anstatt nur die Frage zu beantworten.“ Also, Gut. So erhalten Sie Hilfe beim Schreiben von Software sollen Sei! Wenn ich der guten Praxis widerspreche, Ich möchte es wissen.
– jpmc26
3. April 2019 um 3:52 Uhr
Hier ist die Lösung, die für mich funktioniert:
Ich mache die relativen Importe so from ..sub2 import mod2
und dann, wenn ich laufen will mod1.py dann gehe ich in das übergeordnete Verzeichnis von app und führen Sie das Modul mit dem python -m Schalter als aus python -m app.sub1.mod1.
Der eigentliche Grund, warum dieses Problem bei relativen Importen auftritt, ist, dass relative Importe funktionieren, indem sie die __name__ Eigenschaft des Moduls. Wenn das Modul direkt ausgeführt wird, dann __name__ ist eingestellt auf __main__ und es enthält keine Informationen über die Paketstruktur. Und deshalb beschwert sich Python über die relative import in non-package Fehler.
Wenn Sie also den Schalter -m verwenden, stellen Sie Python die Paketstrukturinformationen zur Verfügung, wodurch die relativen Importe erfolgreich aufgelöst werden können.
Ich bin bei relativen Importen oft auf dieses Problem gestoßen. Und nachdem ich alle vorherigen Antworten gelesen hatte, konnte ich immer noch nicht herausfinden, wie ich es auf saubere Weise lösen konnte, ohne dass ich Boilerplate-Code in alle Dateien einfügen musste. (Obwohl einige der Kommentare wirklich hilfreich waren, danke an @ncoghlan und @XiongChiamiov)
Ich hoffe, das hilft jemandem, der mit relativen Importproblemen zu kämpfen hat, denn das Durchlaufen von PEP macht wirklich keinen Spaß.
Beste Antwort IMHO: erklärt nicht nur, warum OP das Problem hatte, sondern findet auch einen Weg, es zu lösen ohne die Art und Weise zu ändern, wie seine Module Importe durchführen. Schließlich waren die relativen Importe von OP in Ordnung. Der Schuldige war der fehlende Zugriff auf äußere Pakete, wenn es direkt als Skript ausgeführt wurde, etwas -m wurde entwickelt, um zu lösen.
– MestreLion
7. November 2013 um 3:40 Uhr
Beachten Sie auch: Diese Antwort war 5 Jahre nach der Frage. Diese Funktionen waren damals noch nicht verfügbar.
– Jeremy Kun
1. April 2014 um 21:05 Uhr
Wenn Sie ein Modul aus demselben Verzeichnis importieren möchten, können Sie dies tun from . import some_module.
– Rotareti
16. September 2016 um 23:47 Uhr
Dies ist die Antwort, die mir geholfen hat, und sie hat mir auch geholfen, meine Gedanken auf Folgendes zu verdichten: Um ein Python-Skript auszuführen, das relative Importe enthält, muss ich das Skript währenddessen als Modul ausführen $ PWD ist sein übergeordnetes Verzeichnis wie $ python -m app.main. Zur Klarheit, $ python -m <main_directory>.<script_with_relative_imports>
Alternativ könnten 2 oder 3 verwenden: from app.package_a import module_a
Das wird so lange funktionieren, wie Sie haben app in Ihrem PYTHONPATH. main.py könnte dann überall sein.
Also schreibst du a setup.py das gesamte App-Paket und Unterpakete in die Python-Ordner des Zielsystems zu kopieren (installieren) und main.py in die Skriptordner des Zielsystems.
Ausgezeichnete Antwort. Gibt es eine Möglichkeit, auf diese Weise zu importieren, ohne das Paket in PYTHONPATH zu installieren?
dann müssen Sie eines Tages den Namen der App in test_app ändern. was würde passieren? Sie müssen alle Quellcodes ändern, app.package_b.module_b importieren –> test_app.package_b.module_b. das ist absolut SCHLECHTE Vorgehensweise… Und wir sollten versuchen, den relativen Import innerhalb des Pakets zu verwenden.
– Spybdai
16. Dezember 2016 um 11:30 Uhr
Lesnik
“Guido betrachtet das Ausführen von Skripten innerhalb eines Pakets als Anti-Pattern” (abgelehnt PEP-3122)
Ich habe so viel Zeit damit verbracht, eine Lösung zu finden, verwandte Beiträge hier auf Stack Overflow zu lesen und mir zu sagen: “Es muss einen besseren Weg geben!”. Anscheinend gibt es das nicht.
Роман Арсеньев
Das ist zu 100% gelöst:
Anwendung/
main.py
Einstellungen/
local_settings.py
Einstellungen/local_setting.py in app/main.py importieren:
Danke! Alle Leute haben mich gezwungen, mein Skript anders auszuführen, anstatt mir zu sagen, wie ich es innerhalb des Skripts lösen soll. Aber ich musste den Code ändern, um ihn zu verwenden sys.path.insert(0, "../settings") und dann from local_settings import *
– Vit Bernatik
4. November 2016 um 20:22 Uhr
Können Sie bitte Ihre Antwort erläutern? Zum Beispiel, Warum funktioniert es? Wie funktioniert es? Was ist das Wesentliche? “Erklärung ist entscheidend für eine gute Antwort.”_. (Aber ***** ***** ***** ohne ***** ***** ***** “Bearbeiten:”, “Aktualisieren:” oder ähnliches – die Antwort sollte so aussehen, als wäre sie heute geschrieben worden)
def print_a():
print 'This is a function in dir package_a'
app/package_b/fun_b.py
from app.package_a.fun_a import print_a
def print_b():
print 'This is a function in dir package_b'
print 'going to call a function in dir package_a'
print '-'*30
print_a()
main.py
from app.package_b import fun_b
fun_b.print_b()
Wenn du läufst python main.py es gibt zurück:
This is a function in dir package_b
going to call a function in dir package_a
------------------------------
This is a function in dir package_a
main.py macht: from app.package_b import fun_b
fun_b.py tut es from app.package_a.fun_a import print_a
also Datei im Ordner package_b verwendete Datei im Ordner package_a, was du willst. Rechts??
Danke! Alle Leute haben mich gezwungen, mein Skript anders auszuführen, anstatt mir zu sagen, wie ich es innerhalb des Skripts lösen soll. Aber ich musste den Code ändern, um ihn zu verwenden sys.path.insert(0, "../settings") und dann from local_settings import *
– Vit Bernatik
4. November 2016 um 20:22 Uhr
Können Sie bitte Ihre Antwort erläutern? Zum Beispiel, Warum funktioniert es? Wie funktioniert es? Was ist das Wesentliche? “Erklärung ist entscheidend für eine gute Antwort.”_. (Aber ***** ***** ***** ohne ***** ***** ***** “Bearbeiten:”, “Aktualisieren:” oder ähnliches – die Antwort sollte so aussehen, als wäre sie heute geschrieben worden)
– Peter Mortensen
28. März um 14:59 Uhr
Peter Mortensen
Verwenden:
def import_path(fullpath):
"""
Import a file with full path specification. Allows one to
import from anywhere, something __import__ does not do.
"""
path, filename = os.path.split(fullpath)
filename, ext = os.path.splitext(filename)
sys.path.append(path)
module = __import__(filename)
reload(module) # Might be out of date
del sys.path[-1]
return module
Ich verwende dieses Snippet, um Module aus Pfaden zu importieren.
Ich verwende dieses Snippet, kombiniert mit dem imp-Modul (wie hier erklärt [1]) mit großer Wirkung. [1]: stackoverflow.com/questions/1096216/…
– Xiong Tschamiow
16. Juli 2009 um 21:20 Uhr
Wahrscheinlich sollte sys.path.append(path) durch sys.path.insert(0, path) und sys.path ersetzt werden[-1] sollte durch sys.path ersetzt werden[0]. Andernfalls importiert die Funktion das falsche Modul, wenn bereits ein Modul mit demselben Namen im Suchpfad vorhanden ist. Wenn sich zB “some.py” im aktuellen Verzeichnis befindet, importiert import_path(“/imports/some.py”) die falsche Datei.
– Alex Che
16. Juni 2010 um 8:24 Uhr
Ich stimme zu! Manchmal haben andere relative Importe Vorrang. Verwenden Sie sys.path.insert
– iElektrisch
19. Juni 2010 um 7:13 Uhr
Wie würden Sie das Verhalten von from x import y (oder *) replizieren?
– Leveske
7. Dezember 2010 um 19:26 Uhr
Es ist nicht klar, bitte geben Sie die vollständige Nutzung dieses Skripts an, um das OP-Problem zu lösen.
– Mrgloom
24. September 2018 um 13:12 Uhr
14490200cookie-checkWie kann ich relative Importe in Python durchführen?yes
Ich empfehle, Ihre Frage zu aktualisieren, um deutlicher zu machen, dass Sie das in PEP 366 behandelte Problem beschreiben.
– Johannes B
16. September 2008 um 19:36 Uhr
Es ist eine langwierige Erklärung, aber überprüfen Sie hier: stackoverflow.com/a/10713254/1267156 Ich habe eine sehr ähnliche Frage beantwortet. Ich hatte das gleiche Problem bis gestern Abend.
– Sevvy325
23. Mai 2012 um 4:05 Uhr
Für diejenigen, die ein Modul laden möchten, das sich in einem beliebigen Pfad befindet, siehe hier: stackoverflow.com/questions/67631/…
– Jewgeni Sergejew
8. Juni 2014 um 6:29 Uhr
In diesem Zusammenhang wird Python 3 die Standardbehandlung von Importen so ändern, dass sie standardmäßig absolut ist. relative Importe müssen explizit angegeben werden.
– Roß
30. März 2015 um 23:28 Uhr