Python exec ()

Il metodo exec () esegue il programma creato dinamicamente, che può essere una stringa o un oggetto codice.

La sintassi di exec():

 exec (oggetto, globali, locali)

parametri exec ()

exec() accetta tre parametri:

  • oggetto : una stringa o un oggetto codice
  • 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 sarà discusso più avanti nell'articolo.

Valore restituito da exec ()

exec()non restituisce alcun valore, restituisce None.

Esempio 1: come funziona exec ()?

 program = 'a = 5b=10print("Sum =", a+b)' exec(program)

Produzione

 Somma = 15

Qui viene passato il programma oggetto stringa a exec()cui esegue il programma. globals e locals vengono omessi in questo caso.

Esempio 2: Consenti all'utente di fornire input

  program = input('Enter a program:') exec(program) 

Produzione

 Immettere un programma: (print (item) for item in (1, 2, 3)) 1 2 3

Se vuoi prendere il codice Python dall'utente che consente il codice multilinea (usando ''), puoi usare il compile()metodo prima dell'uso exec().

Ulteriori informazioni sul metodo compile () in Python.

Fai attenzione quando usi exec ()

Considera una situazione, stai usando 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 un file.

Se si consente agli utenti di inserire un valore utilizzando exec(input()), l'utente può inviare comandi per modificare il file o anche eliminare tutti i file utilizzando il comando os.system('rm -rf *').

Se stai usando exec(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 * exec('print(dir())')

Produzione

('In', 'Out', '_', '__', '___', '__builtin__', '__builtins__', '__name__', '_dh', '_i', '_i1', '_i2', ' _ih ',' _ii ',' _iii ',' _oh ',' _sh ',' acos ',' acosh ',' asin ',' asinh ',' atan ',' atan2 ',' atanh ',' ceil ' , "copysign", "cos", "cosh", "degree", "e", "erf", "erfc", "exit", "exp", "expm1", "fabs", "factorial", " floor "," fmod "," frexp "," fsum "," gamma "," gcd "," get_ipython "," hypot "," inf "," isclose "," isfinite "," isinf "," isnan " , "ldexp", "lgamma "," log "," log10 "," log1p "," log2 "," modf "," nan "," pi "," pow "," quit "," radianti "," sin "," sinh " , "sqrt", "tan", "tanh", "trunc")

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

Il più delle volte, tutti i metodi e le variabili disponibili utilizzati in exec()potrebbero non essere necessari, o addirittura potrebbero presentare una falla di sicurezza. È possibile limitare l'uso di queste variabili e metodi passando parametri globali e locali facoltativi (dizionari) al exec()metodo.

1. Vengono omessi sia i parametri globali che quelli locali

Se entrambi i parametri vengono omessi (come nei nostri esempi precedenti), il codice che dovrebbe essere eseguito da exec()viene eseguito nell'ambito corrente. È possibile controllare le variabili e i metodi disponibili utilizzando il codice seguente:

 exec ('print (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 ().

3. Passaggio di un dizionario vuoto come parametro globale

 from math import * exec('print(dir())', ()) # This code will raise an exception # exec('print(sqrt(9))', ())

Se si passa un dizionario vuoto come globali, solo i __builtins__sono disponibili per il object(primo parametro per exec ()). Anche se abbiamo importato il modulo matematico nel programma precedente, il tentativo di accedere a una qualsiasi delle funzioni fornite dal modulo matematico solleverà un'eccezione.

Produzione

 ('__builtins__')

Rendere disponibili determinati metodi

 from math import * exec('print(dir())', ('sqrt': sqrt, 'pow': pow)) # object can have sqrt() module exec('print(sqrt(9))', ('sqrt': sqrt, 'pow': pow))

Qui, il codice eseguito da exec () può avere anche metodi sqrt()e .pow()__builtins__

È possibile modificare il nome del metodo secondo il proprio desiderio.

 from math import * exec('print(dir())', ('squareRoot': sqrt, 'pow': pow)) # object can have squareRoot() module exec('print(squareRoot(9))', ('squareRoot': sqrt, 'pow': pow))

Nel programma sopra, squareRoot()calcola la radice quadrata (funzionalità simile come sqrt()). Tuttavia, provare a utilizzare sqrt()solleverà un'eccezione.

Limitazione dell'uso di built-in

È possibile limitare l'uso di __builtins__dando valore Nonea '__builtins__'nel dizionario globale.

 exec (oggetto, ('__builtins__': Nessuno)) 

4. Passaggio del dizionario sia globale che locale

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

 from math import * globalsParameter = ('__builtins__' : None) localsParameter = ('print': print, 'dir': dir) exec('print(dir())', globalsParameter, localsParameter)

Produzione

 ('dir', 'print') 

Qui, solo due metodi predefiniti print () e dir () possono essere eseguiti dal exec()metodo.

È importante notare che, exec()esegue il codice e non restituisce alcun valore (restituisce None). Pertanto, non è possibile utilizzare istruzioni return e yield al di fuori delle definizioni di funzione.

Articoli interessanti...