Es scheint, dass sie in Python 3 auf einfache Weise abgebrochen wurden, um ein Skript durch Entfernen schnell zu laden execfile()
Gibt es eine offensichtliche Alternative, die mir fehlt?
Es scheint, dass sie in Python 3 auf einfache Weise abgebrochen wurden, um ein Skript durch Entfernen schnell zu laden execfile()
Gibt es eine offensichtliche Alternative, die mir fehlt?
reload
ist zurück, daimp.reload
seit 3.2.%run script_name
mit allen Python-Versionen.imp
istimportlib
(was importiert werden muss):importlib.reload(mod_name)
importiert und führt ausmod_name
.runfile()
da ich ein Python-Skript ausführen musste, das in einem eigenen Namespace ausgeführt wird (im Gegensatz zur Ausführung im aufrufenden Namespace). Meine Anwendung: Fügen Sie das Verzeichnis des aufgerufenen Skriptssys.path
mit dem__file__
Attribut zum Systempfad ( ) hinzu : Wenn wirexecfile()
Python 3 (exec(open('file.py').read())
) oder dessen Äquivalent verwenden, wird das enthaltene Skript im aufrufenden Namespace ausgeführt und daher__file__
in den aufrufenden Dateinamen aufgelöst.Antworten:
Laut Dokumentation statt
Verwenden
Sehen:
quelle
close
diese Datei behandeln. Ein weiterer Grund, die Änderung von Python 2 nicht zu mögen.Sie müssen nur die Datei lesen und den Code selbst ausführen. 2to3 Strom ersetzt
wie
(Der Kompilierungsaufruf wird nicht unbedingt benötigt, ordnet jedoch den Dateinamen dem Codeobjekt zu, was das Debuggen etwas erleichtert.)
Sehen:
quelle
exec
es sich um eine Anweisung in python2 handelt,exec(code)
funktioniert sie, weil die Parens einfach ignoriert werden."somefile.py"
Inhalt,inspect.getsourcefile(lambda _: None)
der ohne die Kompilierung fehlschlug, weil dasinspect
Modul nicht feststellen konnte, woher der Code kam.open("somefile.py")
kann falsch sein, wennsomefile.py
eine andere Zeichencodierung als verwendet wirdlocale.getpreferredencoding()
.tokenize.open()
könnte stattdessen verwendet werden.Obwohl
exec(open("filename").read())
es oft als Alternative zu gegeben wirdexecfile("filename")
, fehlen wichtige Details, dieexecfile
unterstützt werden.Die folgende Funktion für Python3.x ist so nah wie möglich am gleichen Verhalten wie das direkte Ausführen einer Datei. Das passt zum Laufen
python /path/to/somefile.py
.Anmerkungen:
__main__
, einige Skripte hängen davon ab, um zu überprüfen, ob sie als Modul geladen werden oder nicht, z.if __name__ == "__main__"
__file__
ist für Ausnahmemeldungen__file__
besser und einige Skripte verwenden , um die Pfade anderer Dateien relativ zu ihnen abzurufen.Nimmt optionale globale und lokale Argumente auf und
execfile
ändert sie an Ort und Stelle. So können Sie auf alle Variablen zugreifen, die durch Zurücklesen der Variablen nach dem Ausführen definiert wurden.Im Gegensatz zu Python2
execfile
ändert dies standardmäßig nicht den aktuellen Namespace. Dafür müssen Sieglobals()
& explizit übergebenlocals()
.quelle
Wie kürzlich auf der Python-Dev- Mailingliste vorgeschlagen, ist das Runpy- Modul möglicherweise eine praktikable Alternative. Zitat aus dieser Nachricht:
Es gibt subtile Unterschiede zu
execfile
:run_path
Erstellt immer einen neuen Namespace. Es führt den Code als Modul aus, sodass es keinen Unterschied zwischen globalen und lokalen Elementen gibt (weshalb es nur eininit_globals
Argument gibt). Die Globals werden zurückgegeben.execfile
im aktuellen Namespace oder im angegebenen Namespace ausgeführt. Die Semantik vonlocals
undglobals
, falls angegeben, ähnelte den Einheimischen und Globalen innerhalb einer Klassendefinition.run_path
kann nicht nur Dateien, sondern auch Eier und Verzeichnisse ausführen (Einzelheiten finden Sie in der Dokumentation).quelle
file_globals
? Dies würde es ersparen, dasfile_globals['...']
für jede Variable eingeben zu müssen.Dieser ist besser, da er die Anrufer und Einheimischen vom Anrufer nimmt:
quelle
execfile
. Es funktionierte sogar für mich, wenn ich Pytests verwendete, bei denen andere oben angegebene Lösungen fehlschlugen. Danke! :)Sie könnten Ihre eigene Funktion schreiben:
Wenn Sie wirklich ...
quelle
globals
undlocals
zeigen Sie auf die globale Namespace fo das Modul die Definition enthält ,execfile()
anstatt auf den globalen und lokalen Namensraum des Anrufers. Der richtige Ansatz besteht darin,None
als Standardwert die globalen und lokalen Werte des Anrufers über die Introspektionsfunktionen desinspect
Moduls zu bestimmen .Wenn sich das Skript, das Sie laden möchten, im selben Verzeichnis befindet wie das, das Sie ausführen, erledigt "import" möglicherweise die Aufgabe?
Wenn Sie Code dynamisch importieren müssen, sollten Sie sich die integrierte Funktion __ import__ und das Modul imp ansehen .
test.py:
Wenn Sie Python 3.1 oder höher verwenden, sollten Sie auch einen Blick darauf werfen importlib ansehen .
quelle
importlib
dev.to/0xcrypto/dynamic-importing-stuff-in-python--1805Folgendes hatte ich (
file
ist in beiden Beispielen bereits dem Pfad zur Datei mit dem Quellcode zugeordnet):Folgendes habe ich ersetzt:
Mein Lieblingsteil: Die zweite Version funktioniert sowohl in Python 2 als auch in Python 3 einwandfrei, was bedeutet, dass es nicht erforderlich ist, eine versionabhängige Logik hinzuzufügen.
quelle
Beachten Sie, dass das obige Muster fehlschlägt, wenn Sie PEP-263-Codierungsdeklarationen verwenden, die nicht ASCII oder UtF-8 sind. Sie müssen die Codierung der Daten finden und korrekt codieren, bevor Sie sie an exec () übergeben.
quelle
Auch wenn Sie keine reine Python-Lösung sind, können Sie mit IPython (wie Sie es wahrscheinlich sowieso tun sollten) Folgendes tun:
Welches ist ebenso einfach.
quelle
Ich bin nur ein Neuling hier, also ist es vielleicht reines Glück, wenn ich Folgendes gefunden habe:
Nachdem Sie versucht haben, ein Skript an der Interpreter-Eingabeaufforderung >>> mit dem Befehl auszuführen
für die ich einen "NameError: Name 'execfile' ist nicht definiert" bekam, habe ich einen sehr einfachen versucht
es hat gut funktioniert :-)
Ich hoffe, dass dies hilfreich sein kann und danke Ihnen allen für die großartigen Hinweise, Beispiele und all die meisterhaft kommentierten Codeteile, die eine großartige Inspiration für Neulinge sind!
Ich benutze Ubuntu 16.014 LTS x64. Python 3.5.2 (Standard, 17. November 2016, 17:05:23) [GCC 5.4.0 20160609] unter Linux
quelle
Für mich ist der sauberste Ansatz,
importlib
die Datei als Modul nach Pfad zu verwenden und zu importieren, wie folgt:Anwendungsbeispiel
Lassen Sie uns eine Datei haben
foo.py
:Jetzt einfach importieren und wie ein normales Modul verwenden:
Ich bevorzuge diese Technik gegenüber direkten Ansätzen,
exec(open(...))
weil sie Ihre Namespaces nicht überladen oder unnötig durcheinander bringt$PATH
.quelle