HOWTO · Python

Starten Sie das Skript in Python neu

Dieses Tutorial zeigt, wie Sie das Programm innerhalb des Programms in Python neu starten

Auf dieser Seite

Um ein Python-Skript neu zu starten, entscheiden Sie zunächst, ob Sie einen neuen Interpreterprozess benötigen oder lediglich die Arbeit Ihres Programms wiederholen möchten. os.execv() ersetzt den aktuellen Prozess, subprocess.call() startet einen untergeordneten Prozess und wartet auf ihn, und eine Schleife kann die Anwendungslogik erneut ausführen, ohne Python neu zu starten.

Methode 1: Den aktuellen Prozess mit os.execv() ersetzen

Verwenden Sie os.execv(), wenn der aktuelle Interpreter durch einen neuen Lauf desselben Skripts ersetzt werden soll. Übergeben Sie den aktiven Interpreter als ausführbare Datei und die Argumentliste des Skripts als Argumente:

os.execv(sys.executable, [sys.executable, *sys.argv])

Importieren Sie os und sys und rufen Sie diesen Ausdruck auf, sobald die Neustartbedingung erfüllt ist. sys.argv enthält den Skriptpfad und die übergebenen Argumente, sodass der neue Interpreter sie erneut erhält. Ein erfolgreicher Aufruf von execv() kehrt nicht zum alten Python-Code zurück: Das Betriebssystem führt das Ersatzprogramm im selben Prozess aus. Leeren Sie vorher alle Ausgabepuffer, deren Inhalt erhalten bleiben soll. Dieser Vorgang ist plattformabhängig; das Beispiel wird hier nicht als ausgeführt dargestellt.

Methode 2: Mit subprocess.call() einen neuen Prozess starten

Verwenden Sie subprocess.call(), wenn ein separater Interpreter das Skript ausführen soll, während der aktuelle Prozess als übergeordneter Prozess bestehen bleibt. Der Aufruf lautet subprocess.call([sys.executable, *sys.argv]); importieren Sie zuvor subprocess und sys. Die Funktion wartet, bis der untergeordnete Prozess beendet ist, und gibt dann dessen Rückgabestatus an den übergeordneten Prozess zurück. Dieser wird nicht automatisch beendet. Soll er nach dem Aufruf aufhören, kehren Sie im entsprechenden Neustartzweig zurück oder beenden Sie ihn. Der untergeordnete Prozess kann dieselbe Neustartlogik übernehmen; stellen Sie daher sicher, dass die Bedingung irgendwann das Ende des Laufs ermöglicht. Das Starten eines Prozesses wird hier nicht anhand einer ausgegebenen Ausführung gezeigt.

Methode 3: Programmlogik mit einer Schleife wiederholen

Wenn nur die Arbeit der Anwendung erneut ausgeführt werden soll, legen Sie diese in eine Funktion und rufen Sie sie in einer kontrollierten Schleife auf. So bleibt derselbe Interpreter erhalten und es entsteht keine Kette untergeordneter Prozesse. Das Beispiel verwendet eine feste Folge von Auswahlmöglichkeiten, um zwei Durchläufe und einen geordneten Ausstieg zu zeigen. Ersetzen Sie die Folge durch Ihre Eingabe oder die Bedingung Ihrer Anwendung.

Führen Sie dieses Beispiel aus:

def run_task(number):
    print(f"Run {number}")

for number, action in enumerate(("restart", "restart", "exit"), start=1):
    if action == "exit":
        print("Done")
        break
    run_task(number)
Run 1
Run 2
Done

In einem echten Kommandozeilenprogramm lesen Sie bei jedem Durchlauf eine Aktion ein und rufen run_task() nur dann auf, wenn der Benutzer die Wiederholung auswählt. Legen Sie eine eindeutige Abbruchbedingung fest. Der erneute Aufruf einer Funktion setzt weder globale Modulvariablen noch geöffnete Ressourcen oder den Interpreterzustand zurück. Schließen oder initialisieren Sie daher alles neu, was beim nächsten Durchlauf nicht weiterverwendet werden soll.

Die passende Neustartmethode auswählen

Verwenden Sie os.execv(), um den Prozess eines einmalig laufenden Skripts zu ersetzen, subprocess.call(), wenn der übergeordnete Prozess auf einen separaten Lauf warten soll, und eine Schleife, wenn ausgewählte Anwendungsaufgaben wiederholt werden sollen. Die Methoden haben unterschiedliche Prozesslebenszyklen: Nach der Ersetzung gibt es keinen alten Python-Stack, zu dem zurückgekehrt werden kann; beim untergeordneten Prozess bleibt der übergeordnete Prozess während des Wartens bestehen; eine Schleife behält den Zustand des aktuellen Interpreters bei. Verwenden Sie für einen Webdienst dessen Prozessmanager oder Bereitstellungssteuerung, statt einen Worker aus einem Anfrage-Handler neu zu starten. Ein Neustart während einer Anfrage kann Benutzer unterbrechen und im Arbeitsspeicher gehaltene Zustände verlieren.

Häufig gestellte Fragen

Welche Methode sollte ich wählen?

Verwenden Sie eine Schleife für wiederholte Anwendungsaktionen, os.execv() zum Ersetzen des aktuellen Prozesses oder subprocess.call(), wenn ein übergeordneter Prozess auf einen neuen Interpreterlauf warten muss.

Kann sich ein Skript automatisch neu starten?

Ja. Eine Bedingung, etwa eine Änderung der Konfiguration, kann einen Neustart auslösen, ohne dass der Benutzer dazu aufgefordert wird. Achten Sie darauf, dass die Bedingung irgendwann falsch wird oder der Neustartzyklus auf andere Weise endet.

Beeinflusst ein Neustart die Leistung?

Ein Interpreterstart verursacht Aufwand; häufige Neustarts können außerdem Initialisierungsarbeiten wiederholen. Eine Schleife vermeidet diesen Prozessstart, behält aber den Zustand des aktuellen Interpreters bei, der möglicherweise ausdrücklich bereinigt werden muss.

Kann ich beim Neustart geänderte Argumente übergeben?

Ja. Erstellen Sie für os.execv() oder subprocess.call() eine neue Argumentliste, statt sys.argv unverändert wiederzuverwenden. Setzen Sie den Interpreter an die erste Stelle und geben Sie den Skriptpfad vor den Argumenten Ihrer Anwendung an.

Sollte eine Webanwendung ihr Skript aus einer Anfrage heraus neu starten?

Im Allgemeinen nicht. Ein Worker-Neustart während einer Anfrage kann den Dienst unterbrechen und im Arbeitsspeicher gehaltene Zustände verwerfen. Verwenden Sie den vorgesehenen Neustart- und Bereitstellungsmechanismus des Servers oder Prozessmanagers.