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 os
modulo. 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 None
a '__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.