Python eval ()

Il metodo eval () analizza l'espressione passata a questo metodo ed esegue l'espressione (codice) python all'interno del programma.

In termini semplici, la eval()funzione esegue il codice python (che viene passato come argomento) all'interno del programma.

La sintassi di eval()è:

 eval (espressione, globals = None, locals = None)

eval () Parametri

La eval()funzione accetta tre parametri:

  • espressione : la stringa analizzata e valutata come un'espressione Python
  • globals (opzionale) - un dizionario
  • locals (opzionale): un oggetto di mappatura. Il dizionario è il tipo di mappatura standard e comunemente usato in Python.

L'uso di globali e locali verrà discusso più avanti in questo articolo.

Valore restituito da eval ()

Il metodo eval () restituisce il risultato valutato dall'espressione.

Esempio 1: come funziona eval () in Python

 x = 1 print(eval('x + 1'))

Produzione

 2

Qui, la eval()funzione valuta l'espressione x + 1e printviene utilizzata per visualizzare questo valore.

Esempio 2: esempio pratico per dimostrare l'uso di eval ()

 # Perimeter of Square def calculatePerimeter(l): return 4*l # Area of Square def calculateArea(l): return l*l expression = input("Type a function: ") for l in range(1, 5): if (expression == 'calculatePerimeter(l)'): print("If length is ", l, ", Perimeter = ", eval(expression)) elif (expression == 'calculateArea(l)'): print("If length is ", l, ", Area = ", eval(expression)) else: print('Wrong Function') break

Produzione

 Digita una funzione: calcolaArea (l) Se la lunghezza è 1, Area = 1 Se la lunghezza è 2, Area = 4 Se la lunghezza è 3, Area = 9 Se la lunghezza è 4, Area = 16

Avvisi quando si usa eval ()

Considera una situazione in cui stai utilizzando un sistema Unix (macOS, Linux, ecc.) E hai importato il osmodulo. Il modulo os fornisce un modo portatile per utilizzare le funzionalità del sistema operativo come leggere o scrivere su un file.

Se si consente agli utenti di inserire un valore utilizzando eval(input()), l'utente può inviare comandi al file di modifica o addirittura eliminare tutti i file utilizzando il comando: os.system('rm -rf *').

Se stai usando eval(input())nel tuo codice, è una buona idea controllare quali variabili e metodi l'utente può usare. Puoi vedere quali variabili e metodi sono disponibili usando il metodo dir ().

 from math import * print(eval('dir()'))

Produzione

('__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', ' asinh "," atan "," atan2 "," atanh "," ceil "," comb "," copysign "," cos "," cosh "," degree "," dist "," e "," erf " , "erfc", "exp", "expm1", "fabs", "factorial", "floor", "fmod", "frexp", "fsum", "gamma", "gcd", "hypot", " inf ',' isclose ',' isfinite ',' isinf ',' isnan ',' isqrt ',' ldexp ',' lgamma ',' log ',' log10 ',' log1p ','log2 "," modf "," nan "," os "," perm "," pi "," pow "," prod "," radians "," remainder "," sin "," sinh "," sqrt " , "tan", "tanh", "tau", "trunc")

Limitazione dell'uso dei metodi e delle variabili disponibili in eval ()

Il più delle volte, tutti i metodi e le variabili disponibili utilizzati nell'espressione (il primo parametro a eval()) potrebbero non essere necessari o addirittura potrebbero presentare un buco di sicurezza. Potrebbe essere necessario limitare l'uso di questi metodi e variabili per eval(). È possibile farlo passando i parametri globali e locali facoltativi (dizionari) alla eval()funzione.

1. Quando vengono omessi sia i parametri globali che quelli locali

Se entrambi i parametri vengono omessi (come nei nostri esempi precedenti), l'espressione viene eseguita nell'ambito corrente. È possibile controllare le variabili e i metodi disponibili utilizzando il codice seguente:

 print(eval('dir()')

2. Passaggio di parametri globali; il parametro locals viene omesso

I parametri globali e locali (dizionari) vengono utilizzati rispettivamente per le variabili globali e locali. Se il dizionario locals viene omesso, il valore predefinito è il dizionario globals. Significa che le variabili globali verranno utilizzate sia per le variabili globali che per quelle locali.

Nota: puoi controllare il dizionario globale e locale corrente in Python usando rispettivamente i metodi integrati globals () e locals ().

Esempio 3: passaggio di un dizionario vuoto come parametro globale

 from math import * print(eval('dir()', ())) # The code will raise an exception print(eval('sqrt(25)', ()))

Produzione

 ('__builtins__') Traceback (ultima chiamata più recente): File "", riga 5, in print (eval ('sqrt (25)', ())) File "", riga 1, in NameError: nome 'sqrt' non è definito

Se si passa un dizionario vuoto come globali, solo i __builtins__sono disponibili per expression(primo parametro per eval()).

Anche se abbiamo importato il mathmodulo nel programma precedente, l'espressione non può accedere a nessuna funzione fornita dal modulo matematico.

Esempio 4: rendere disponibili determinati metodi

 from math import * print(eval('dir()', ('sqrt': sqrt, 'pow': pow)))

Produzione

 ('__builtins__', 'pow', 'sqrt')

Qui, l'espressione può utilizzare solo sqrt()i pow()metodi e insieme a __builtins__.

E 'inoltre possibile modificare il nome del metodo disponibile per l'espressione secondo il proprio desiderio:

 from math import * names = ('square_root': sqrt, 'power': pow) print(eval('dir()', names)) # Using square_root in Expression print(eval('square_root(9)', names))

Produzione

 ('__builtins__', 'power', 'square_root') 3.0

Nel programma sopra, square_root()calcola la radice quadrata usando sqrt(). Tuttavia, provare a utilizzare sqrt()direttamente genererà un errore.

Esempio 5: limitazione dell'uso di built-in

È possibile limitare l'uso di __builtins__nell'espressione come segue:

 eval(expression, ('__builtins__': None))

3. Passaggio del dizionario sia globali che locali

È possibile rendere disponibili per l'uso le funzioni e le variabili necessarie passando il dizionario locals. Per esempio:

 from math import * a = 169 print(eval('sqrt(a)', ('__builtins__': None), ('a': a, 'sqrt': sqrt)))

Produzione

 13.0

In questo programma, l'espressione può avere solo sqrt()metodo e variabile a. Tutti gli altri metodi e variabili non sono disponibili.

Limitare l'uso di eval()tramite il passaggio di dizionari globali e locali renderà il codice sicuro in particolare quando si utilizza l'input fornito dall'utente al eval()metodo.

Nota: a volte, eval()non è sicuro anche con nomi limitati. Quando un oggetto e i suoi metodi sono resi accessibili, quasi tutto può essere fatto. L'unico modo sicuro è convalidare l'input dell'utente.

Articoli interessanti...