HOWTO · Python

Riavvia lo script in Python

Questo tutorial mostra come riavviare il programma all'interno del programma in Python

In questa pagina

Per riavviare uno script Python, scegli se ti serve un nuovo processo dell’interprete oppure se vuoi soltanto ripetere il lavoro del programma. os.execv() sostituisce il processo corrente, subprocess.call() avvia un processo figlio e lo attende, mentre un ciclo può eseguire di nuovo la logica dell’applicazione senza riavviare Python.

Metodo 1: sostituire il processo corrente con os.execv()

Usa os.execv() quando vuoi sostituire l’interprete corrente con una nuova esecuzione dello stesso script. Passa l’interprete attivo come eseguibile e l’elenco degli argomenti dello script come argomenti:

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

Importa os e sys, quindi chiama questa espressione quando si verifica la condizione di riavvio. sys.argv include il percorso dello script e gli argomenti ricevuti, quindi il nuovo interprete li riceve di nuovo. Se execv() ha successo, il codice Python precedente non riprende: il sistema operativo esegue il programma sostitutivo nello stesso slot di processo. Prima di sostituire il processo, svuota i buffer di output che vuoi conservare. Questa operazione dipende dalla piattaforma e qui non viene presentata come un esempio eseguito.

Metodo 2: avviare un nuovo processo con subprocess.call()

Usa subprocess.call() quando vuoi che un interprete separato esegua lo script mentre il processo corrente resta il processo padre. La chiamata è subprocess.call([sys.executable, *sys.argv]); importa prima subprocess e sys. Attende che il processo figlio termini, quindi restituisce al padre il codice di uscita del figlio. Il processo padre non termina automaticamente: se deve fermarsi, dopo la chiamata esci dal ramo di riavvio con return o exit. Il figlio potrebbe ereditare la stessa logica di riavvio, quindi assicurati che la condizione consenta infine all’esecuzione di terminare. Qui questo avvio di processo non è presentato come output di un esempio eseguito.

Metodo 3: ripetere la logica del programma con un ciclo

Se vuoi ripetere soltanto il lavoro dell’applicazione, inseriscilo in una funzione e chiamala da un ciclo controllato. In questo modo mantieni lo stesso interprete ed eviti di creare una catena di processi figli. L’esempio usa una sequenza fissa di scelte per mostrare due esecuzioni e un’uscita regolare; sostituisci la sequenza con i tuoi input o con la condizione dell’applicazione.

Esegui questo esempio:

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 un vero programma a riga di comando, leggi un’azione a ogni iterazione e chiama run_task() solo quando l’utente chiede di ripetere l’operazione. Definisci una condizione di uscita chiara. Ripetere una funzione non azzera le variabili globali dei moduli, le risorse aperte o lo stato dell’interprete: chiudi o inizializza di nuovo tutto ciò che non deve essere riutilizzato nell’esecuzione successiva.

Scegliere il metodo di riavvio più adatto

Usa os.execv() per sostituire il processo di uno script eseguito una sola volta, subprocess.call() quando il processo padre deve attendere un’esecuzione separata e un ciclo quando vuoi ripetere una parte selezionata del lavoro dell’applicazione. Questi approcci hanno cicli di vita dei processi diversi: dopo la sostituzione non resta alcun frame Python precedente a cui tornare, l’esecuzione figlia lascia attivo il processo padre durante l’attesa e il ciclo conserva lo stato dell’interprete corrente. Per un servizio web, usa il gestore dei processi o i controlli di distribuzione invece di riavviare un worker da un gestore di richieste: un riavvio durante una richiesta può interrompere gli utenti e far perdere lo stato in memoria.

Domande frequenti

Quale metodo dovrei scegliere?

Scegli un ciclo per ripetere operazioni dell’applicazione, os.execv() per sostituire il processo corrente oppure subprocess.call() quando un processo padre deve attendere una nuova esecuzione dell’interprete.

Uno script può riavviarsi automaticamente?

Sì. Una condizione, come una modifica alla configurazione, può avviare il riavvio senza chiedere conferma all’utente. Assicurati che la condizione possa diventare falsa o che il ciclo di riavvio possa terminare in altro modo.

Il riavvio influisce sulle prestazioni?

Avviare un interprete comporta un costo di avvio e riavvii frequenti possono ripetere le operazioni di inizializzazione. Un ciclo evita questo avvio, ma conserva lo stato dell’interprete corrente, che potrebbe richiedere una pulizia esplicita.

Posso passare argomenti modificati al riavvio?

Sì. Crea un nuovo elenco di argomenti per os.execv() o subprocess.call() invece di riutilizzare sys.argv senza modifiche. Inserisci l’eseguibile dell’interprete come primo elemento e il percorso dello script prima degli argomenti dell’applicazione.

Un’applicazione web dovrebbe riavviare il proprio script in risposta a una richiesta?

In genere, no. Il riavvio di un worker durante una richiesta può interrompere il servizio e cancellare lo stato in memoria. Usa il meccanismo di riavvio e distribuzione supportato dal server o dal gestore dei processi.