Frage

Es scheint, sie in Python 3 alle den einfachen Weg abgebrochen, um schnell einen Skript zu laden, indem execfile() Entfernen

Gibt es eine offensichtliche Alternative fehle ich?

War es hilfreich?

Lösung

Gemäß der Dokumentation , anstelle von

execfile("./filename") 

Mit

exec(open("./filename").read())

Siehe auch:

Andere Tipps

Sie sollen nur die Datei lesen und den Code selbst exec. 2to3 Strom ersetzt

execfile("somefile.py", global_vars, local_vars)

als

with open("somefile.py") as f:
    code = compile(f.read(), "somefile.py", 'exec')
    exec(code, global_vars, local_vars)

(Der Kompilierung Aufruf nicht unbedingt erforderlich ist, aber es ordnet den Dateinamen mit dem Code-Objekt macht das Debuggen ein wenig leichter.)

Siehe auch:

Während exec(open("filename").read()) oft als Alternative gegeben zu execfile("filename"), es fehlt wichtige Details, die unterstützt execfile.

Die folgende Funktion für Python3.x ist so nah wie ich das gleiche Verhalten, wie die Ausführung einer Datei direkt zu bekommen. Das passt läuft python /path/to/somefile.py.

def execfile(filepath, globals=None, locals=None):
    if globals is None:
        globals = {}
    globals.update({
        "__file__": filepath,
        "__name__": "__main__",
    })
    with open(filepath, 'rb') as file:
        exec(compile(file.read(), filepath, 'exec'), globals, locals)

# execute the file
execfile("/path/to/somefile.py")

Weitere Informationen:

  • Verwendet Binär-Lese Codierung Probleme zu vermeiden
  • Garantiert die Datei schließen (Python3.x warnt darüber)
  • __main__ Definiert, hängen einige Skripte auf, dies zu überprüfen, ob sie als Modul oder nicht für zB geladen werden. if __name__ == "__main__"
  • __file__ Einstellung ist schöner für Ausnahmemeldungen und einige Skripte verwenden __file__ die Pfade der anderen Dateien in Bezug auf sie zu erhalten.
  • nimmt optional Globals & Einheimische Argumente, sie an Ort und Stelle zu modifizieren, wie execfile tut -. So können Sie alle Variablen durch das Lesen wieder die Variablen nach der Ausführung definiert Zugriff

  • Im Gegensatz zu Python2 des execfile tut dies nicht die aktuellen Namespace standardmäßig ändern. Dafür müssen Sie explizit in globals() & locals() passieren.

Wie auf der Python-dev vorgeschlagen Mailingliste vor kurzem, könnte das runpy Modul eine brauchbare Alternative sein. Zitiert aus dieser Nachricht:

  

https://docs.python.org/3/library/ runpy.html # runpy.run_path

import runpy
file_globals = runpy.run_path("file.py")

Es gibt subtile Unterschiede execfile:

  • run_path erzeugt immer einen neuen Namespace. Es führt den Code als ein Modul, so gibt es keinen Unterschied zwischen Globals und Einheimischen (weshalb es nur ein init_globals Argument ist). Die Globals zurückgegeben.

    execfile im aktuellen Namespace oder der angegebenen Namespace ausgeführt. Die Semantik von locals und globals, waren, wenn gegeben, ähnlich wie bei Einheimischen und Globals innerhalb einer Klassendefinition.

  • run_path kann nicht nur Dateien ausführen, sondern auch Eier und Verzeichnisse (siehe Details in der jeweiligen Dokumentation).

Dies ist besser, da es die Globals und Einheimische vom Anrufer nimmt:

import sys
def execfile(filename, globals=None, locals=None):
    if globals is None:
        globals = sys._getframe(1).f_globals
    if locals is None:
        locals = sys._getframe(1).f_locals
    with open(filename, "r") as fh:
        exec(fh.read()+"\n", globals, locals)

Sie können Ihre eigene Funktion schreiben:

def xfile(afile, globalz=None, localz=None):
    with open(afile, "r") as fh:
        exec(fh.read(), globalz, localz)

Wenn Sie wirklich benötigt ...

Wenn das Skript Sie laden wollen, ist im selben Verzeichnis als die, die Sie ausführen, vielleicht „Import“ wird die Arbeit machen?

Wenn Sie dynamisch Code importieren Sie die eingebaute Funktion __ __ Import und das Modul imp sich sehen lassen.

>>> import sys
>>> sys.path = ['/path/to/script'] + sys.path
>>> __import__('test')
<module 'test' from '/path/to/script/test.pyc'>
>>> __import__('test').run()
'Hello world!'

test.py:

def run():
        return "Hello world!"

Wenn Sie Python 3.1 oder höher verwenden, sollten Sie auch einen Blick auf nehmen

Hier ist, was ich hatte (file bereits auf den Pfad zur Datei mit dem Quellcode in beiden Beispielen zugeordnet ist):

execfile(file)

Hier ist, was ich ersetzt es mit:

exec(compile(open(file).read(), file, 'exec'))

Mein Lieblingsteil: die zweite Version funktioniert gut sowohl in Python 2 und 3, ist es nicht notwendig, das heißt in Version abhängige Logik hinzufügen

.

Beachten Sie, dass die obigen Muster wird scheitern, wenn Sie PEP-263 Codierungsdeklarationen verwenden , die nicht ASCII- oder UTF-8. Sie müssen die Codierung der Daten finden, und es kodieren richtig vor Aushändigung es () exec.

class python3Execfile(object):
    def _get_file_encoding(self, filename):
        with open(filename, 'rb') as fp:
            try:
                return tokenize.detect_encoding(fp.readline)[0]
            except SyntaxError:
                return "utf-8"

    def my_execfile(filename):
        globals['__file__'] = filename
        with open(filename, 'r', encoding=self._get_file_encoding(filename)) as fp:
            contents = fp.read()
        if not contents.endswith("\n"):
            # http://bugs.python.org/issue10204
            contents += "\n"
        exec(contents, globals, globals)

Auch wenn nicht eine reine Python-Lösung, wenn Sie mit IPython (wie Sie wahrscheinlich sollte sowieso), können Sie tun:

%run /path/to/filename.py

, die ebenso einfach ist.

Ich bin nur ein Neuling hier so vielleicht ist es reines Glück, wenn ich dies gefunden:

Nach dem Versuch, einen Skript aus den Interpreter Prompt >>> mit dem Befehl ausführen

    execfile('filename.py')

, für die ich bekam einen „Nameerror: name‚execfile‘ist nicht definiert“ Ich habe versucht, ein sehr einfaches

    import filename

es hat gut funktioniert: -)

Ich hoffe, dass dies hilfreich sein kann und danke Ihnen allen für die große Hinweise, Beispiele und alle jene meister kommentierte Stücke von Code, der eine große Inspiration für Neulinge!

Ich benutze Ubuntu 16,014 LTS x64. Python 3.5.2 (Standard, 17. November 2016, 17.05.23) [GCC 5.4.0 20160609] auf Linux

scroll top