Metoda exec () provede dynamicky vytvořený program, kterým je buď řetězec, nebo objekt kódu.
Syntaxe exec()
:
exec (objekt, globálové, místní)
Parametry exec ()
exec()
trvá tři parametry:
- objekt - buď řetězec, nebo kódový objekt
- globals (nepovinné) - slovník
- locals (nepovinné) - mapovací objekt. Slovník je standardní a běžně používaný typ mapování v Pythonu.
O použití globálních a místních obyvatel bude pojednáno dále v článku.
Návratová hodnota z exec ()
exec()
nevrátí žádnou hodnotu, vrátí se None
.
Příklad 1: Jak funguje exec ()?
program = 'a = 5b=10print("Sum =", a+b)' exec(program)
Výstup
Součet = 15
Zde je předán program objektového řetězce, který program exec()
provede. Globální a místní obyvatelé jsou v tomto případě vynecháni.
Příklad 2: Povolit uživateli zadat vstup
program = input('Enter a program:') exec(program)
Výstup
Zadejte program: (tisk (položka) pro položku v (1, 2, 3)) 1 2 3
Pokud chcete převzít kód Pythonu od uživatele, který umožňuje víceřádkový kód (pomocí ''
), můžete compile()
před použitím použít metodu exec()
.
Další informace o metodě compile () v Pythonu.
Buďte opatrní při používání exec ()
Zvažte situaci, používáte unixový systém (macOS, Linux atd.) A importovali jste os
modul. Modul os poskytuje přenosný způsob, jak používat funkce operačního systému, jako je čtení nebo zápis souboru.
Pokud povolíte uživatelům zadat hodnotu pomocí exec(input())
, může uživatel vydat příkazy ke změně souboru nebo dokonce smazat všechny soubory pomocí příkazu os.system('rm -rf *')
.
Pokud používáte exec(input())
ve svém kódu, je dobré zkontrolovat, které proměnné a metody může uživatel použít. Pomocí metody dir () můžete zjistit, které proměnné a metody jsou k dispozici.
from math import * exec('print(dir())')
Výstup
('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“, „stupně“, „e“, „erf“, „erfc“, „výstup“, „exp“, „expm1“, „fabs“, „faktoriál“, „ 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 ',' radians ',' sin ',' sinh ' , 'sqrt', 'tan', 'tanh', 'trunc')
Omezení použití dostupných metod a proměnných v exec ()
Více často než ne, všechny dostupné metody a proměnné používané v exec()
nemusí být potřeba, nebo dokonce mohou mít bezpečnostní díru. Můžete omezit použití těchto proměnných a metod předáním volitelných globálních a místních parametrů (slovníků) exec()
metodě.
1. Globální i místní parametry jsou vynechány
Pokud jsou oba parametry vynechány (jako v našich dřívějších příkladech), očekává se kód, který má být spuštěn, exec()
proveden v aktuálním oboru. Dostupné proměnné a metody můžete zkontrolovat pomocí následujícího kódu:
exec ('print (dir ())')
2. Předávání globálních parametrů; parametr locals je vynechán
Parametry globals a locals (slovníky) se používají pro globální a lokální proměnné. Pokud je slovník místních obyvatel vynechán, použije se výchozí slovník globálů. To znamená, že globály budou použity pro globální i místní proměnné.
Poznámka: Aktuální globální a místní slovník v Pythonu můžete zkontrolovat pomocí integrovaných metod globals () a locals ().
3. Předání prázdného slovníku jako globálního parametru
from math import * exec('print(dir())', ()) # This code will raise an exception # exec('print(sqrt(9))', ())
Pokud předáte prázdný slovník jako globály, __builtins__
jsou k dispozici object
(pouze první parametr exec ()) pouze ty. I když jsme do výše uvedeného programu importovali matematický modul, pokus o přístup k jakýmkoli funkcím poskytovaným matematickým modulem vyvolá výjimku.
Výstup
('__builtins__')
Zpřístupnění určitých metod
from math import * exec('print(dir())', ('sqrt': sqrt, 'pow': pow)) # object can have sqrt() module exec('print(sqrt(9))', ('sqrt': sqrt, 'pow': pow))
Here, the code that is executed by exec() can also have sqrt()
and pow()
methods along with __builtins__
.
It's possible to change the name of the method according to your wish.
from math import * exec('print(dir())', ('squareRoot': sqrt, 'pow': pow)) # object can have squareRoot() module exec('print(squareRoot(9))', ('squareRoot': sqrt, 'pow': pow))
In the above program, squareRoot()
calculates the square root (similar functionality like sqrt()
). However, trying to use sqrt()
will raise an exception.
Restricting the Use of built-ins
You can restrict the use of __builtins__
by giving value None
to the '__builtins__'
in the globals dictionary.
exec(object, ('__builtins__': None))
4. Passing both globals and locals dictionary
You can make needed functions and variables available for use by passing locals dictionary. For example:
from math import * globalsParameter = ('__builtins__' : None) localsParameter = ('print': print, 'dir': dir) exec('print(dir())', globalsParameter, localsParameter)
Output
('dir', 'print')
Zde lze exec()
metodou provést pouze dvě vestavěné metody print () a dir () .
Je důležité si uvědomit, že exec()
provede kód a nevrátí žádnou hodnotu (vrátí None
). Proto nemůžete používat příkazy return a yield mimo definice funkcí.