Come utilizzare le funzioni Eval ed Exec in Python

Come utilizzare le funzioni Eval ed Exec in Python

Questo articolo coprirà una guida sull'uso delle funzioni "Eval" e "Exec" disponibili nella Biblioteca Python standard. Queste funzioni possono essere utilizzate in vari modi per valutare ed eseguire le espressioni di Python. L'uso di entrambe queste funzioni può essere meglio compreso attraverso esempi. Alcuni esempi sono elencati di seguito. Tutti i campioni di codice in questo articolo sono testati con Python 3.9.5 su Ubuntu 21.04.

Utilizzo di Eval per valutare le espressioni di Python

La funzione Eval può essere utilizzata per valutare le espressioni di Python e ottenere un valore di ritorno da esse. Qualsiasi espressione di Python che deve essere valutata viene fornita alla funzione Eval sotto forma di un argomento obbligatorio. Le espressioni passate come argomento alle funzioni di Eval hanno pieno accesso alle funzioni di Python integrate, nonché a spazi dei nomi globali e locali. Dai un'occhiata al campione del codice di seguito:

n = 1
risultato = valuta ("n * 2")
Stampa (risultato)
Eval ("Print (N * 2)")

Le citazioni triple nell'esempio sopra vengono utilizzate per presentare le stringhe "così come sono", senza sfuggire ai caratteri speciali o apportare altre modifiche. La prima istruzione nel campione del codice definisce una variabile chiamata "N" con un valore di 1. Successivamente, il metodo Eval viene chiamato fornendolo un'espressione di Python in formato stringa. Nell'espressione della stringa, la variabile "N" è stata referenziata in quanto è già disponibile nello spazio dei nomi. L'istruzione successiva stampa l'output della variabile "risultato". L'ultima affermazione illustra che è possibile chiamare direttamente le funzioni di Python integrate nell'espressione fornita alla funzione Eval come argomento.

Dopo aver eseguito il campione di codice sopra, è necessario ottenere il seguente output:

2
2

Come puoi vedere nell'output sopra, entrambe le istruzioni di stampa producono lo stesso risultato.

È possibile fornire facoltativamente dizionari personalizzati per gli spazi dei nomi globali e locali per limitare e controllare gli oggetti dello spazio dei nomi consentiti. Dai un'occhiata al campione del codice di seguito:

n = 1
risultato = valuta ("n * 2")
Stampa (risultato)
Eval ("Print (M * 2)", 'M': 1)
Eval ("print (n * 2)", 'm': 1)

Nella dichiarazione Eval nella quarta riga, viene fornito un argomento extra in cui viene utilizzato un dizionario di oggetti di spazio dei nomi globali personalizzati. Quando si fornisce un dizionario di oggetti globali personalizzati, solo i metodi e le mappature integrate inclusi nel dizionario vengono utilizzati da Eval. Se si utilizza un dizionario globale vuoto (""), sono consentiti solo metodi integrati e nemmeno importazioni personalizzate. Poiché l'oggetto "M" nel dizionario globale ha un valore di 1, l'istruzione Eval è in grado di utilizzare un riferimento per "M". Nell'ultima affermazione, l'oggetto "M" è disponibile nel dizionario globale, ma non nella variabile "N", poiché è stato fornito un dizionario personalizzato di oggetti globali. L'ultima affermazione lancerà un errore in quanto non esiste una definizione per "n" nel dizionario dello spazio dei nomi globali personalizzato.

Dopo aver eseguito il campione di codice sopra, è necessario ottenere il seguente output:

2
2
Traceback (chiamata più recente per ultima):
File "/home/utente/downloads/./test.py ", riga 7, in
Eval ("print (n * 2)", 'm': 1)
File "", riga 1, in
NameError: nome 'n' non è definito

È possibile utilizzare un dizionario per gli oggetti dello spazio dei nomi locali allo stesso modo degli oggetti dello spazio dei nomi globali. Basta fornire un dizionario personalizzato come terzo argomento affinché la funzione Eval lo usi come una mappatura per gli oggetti dello spazio dei nomi locali.

Utilizzo di Exec per eseguire il codice Python

La funzione Exec funziona in modo simile alla funzione Eval con alcune differenze. L'espressione fornita alla funzione Exec può essere una stringa o qualsiasi altro oggetto Python valido che contiene un codice Python valido. In confronto, la funzione Eval prende solo espressioni di stringa. È inoltre possibile fornire dizionari personalizzati per gli oggetti dello spazio dei nomi sia globali che locali e il metodo Exec si comporta allo stesso modo della funzione Eval quando vengono utilizzate mappature dello spazio dei nomi personalizzate. Un'altra differenza con la funzione Eval è che la funzione Exec restituisce sempre un valore "nessuno". Dai un'occhiata al campione del codice di seguito:

n = 1
risultato = exec ("n * 2")
Stampa (risultato)
Exec ("Print (N * 2)")
risultato = "print (n * 2)"
Exec (risultato)

Il blocco di codice è molto simile al campione di codice utilizzato nell'esempio EVAL, ma invece della funzione Eval, ora è stata utilizzata la funzione Exec. Dopo aver eseguito il campione di codice sopra, è necessario ottenere il seguente output:

Nessuno
2
2

Come affermato in precedenza, la funzione Exec restituisce sempre un valore "nessuno", quindi la terza riga produce "nessuno" come output. Successivamente, l'istruzione EXEC nella quarta riga utilizza la funzione "stampa" per produrre "2" come output. Alla variabile del risultato viene quindi assegnato un nuovo valore fornendole un'istruzione Codice Python valida nel modulo stringa. L'ultima istruzione mostra che la funzione Exec può invocare direttamente gli oggetti del codice contenenti un codice Python valido. Produce anche "2" come output.

Considerazioni sulla sicurezza

Durante l'utilizzo delle funzioni Eval ed Exec, dovresti essere consapevole che entrambe queste funzioni consentono l'esecuzione di espressioni arbitrarie di Python e blocchi di codice. Se non sei consapevolmente consapevole di ciò che viene utilizzato nelle espressioni, queste dichiarazioni possono danneggiare l'ambiente in cui stai lavorando. Ad esempio, è possibile modificare, rimuovere o apportare modifiche irreversibili ai file archiviati sull'host utilizzando i moduli "OS" e "SYS" e i loro metodi nelle funzioni Eval ed Exec. Il modulo "sottoprocesso" in Python consente di avviare nuovi processi ed eseguire comandi shell. Le espressioni nei metodi Eval ed Exec che utilizzano il modulo del sottoprocesso possono portare a comportamenti non intenzionali se non si sta attenti a ciò che viene utilizzato nelle espressioni.

Conclusione

Entrambi i metodi Eval e Exec consentono di elaborare ed eseguire blocchi di codice Python. È possibile fornire dichiarazioni di valutazione ad altre funzioni di Python come argomenti in quanto restituiscono sempre un valore, in qualche modo simili alle funzioni Lambda in Python. Allo stesso modo, è possibile utilizzare la funzione Exec per eseguire il codice Python predefinito. È più comunemente usato dove è necessario leggere il codice Python da un file ed eseguito in un altro.