Python eval ()

Metoda eval () analyzuje výraz předaný této metodě a spouští výraz (kód) pythonu v rámci programu.

Jednoduše řečeno, eval()funkce spouští v programu kód pythonu (který se předává jako argument).

Syntaxe eval()je:

 eval (výraz, globální = žádný, místní = žádný)

eval () Parametry

eval()Funkce má tři parametry:

  • expression - řetězec analyzovaný a vyhodnocený jako výraz v Pythonu
  • 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álů a místních obyvatel pojednává dále v tomto článku.

Návratová hodnota z eval ()

Metoda eval () vrací výsledek vyhodnocený z výrazu.

Příklad 1: Jak funguje eval () v Pythonu

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

Výstup

 2

Zde eval()funkce vyhodnotí výraz x + 1a printpoužije se k zobrazení této hodnoty.

Příklad 2: Praktický příklad k prokázání použití funkce 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

Výstup

 Zadejte funkci: CalcArea (l) Je-li délka 1, Plocha = 1 Je-li délka 2, Plocha = 4 Pokud je délka 3, Plocha = 9 Pokud je délka 4, Plocha = 16

Varování při použití eval ()

Zvažte situaci, kdy používáte unixový systém (macOS, Linux atd.) A osmodul jste importovali . Modul os poskytuje přenosný způsob, jak používat funkce operačního systému, jako je čtení nebo zápis do souboru.

Máte-li uživatelům umožnit vstup hodnotu pomocí eval(input())může uživatel vydávat příkazy do souboru změnit nebo dokonce odstranit všechny soubory pomocí příkazu: os.system('rm -rf *').

Pokud používáte eval(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 * print(eval('dir()'))

Výstup

('__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', ' asinh ',' atan ',' atan2 ',' atanh ',' ceil ',' hřeben ',' copysign ',' cos ',' cosh ',' stupňů ',' dist ',' e ',' erf ' „erfc“, „exp“, „expm1“, „fabs“, „faktoriál“, „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 ',' radiány ',' zbytek ',' sin ',' sinh ',' sqrt ' , 'tan', 'tanh', 'tau', 'trunc')

Omezení použití dostupných metod a proměnných v eval ()

Častěji nemusí být k dispozici všechny dostupné metody a proměnné použité ve výrazu (první parametr do eval()), nebo dokonce mohou mít bezpečnostní díru. Možná budete muset omezit použití těchto metod a proměnných pro eval(). Můžete tak učinit předáním volitelných globálních a místních parametrů (slovníků) do eval()funkce.

1. Když jsou vynechány globální i místní parametry

Pokud jsou oba parametry vynechány (jako v našich dřívějších příkladech), je výraz spuštěn v aktuálním oboru. Dostupné proměnné a metody můžete zkontrolovat pomocí následujícího kódu:

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

Příklad 3: Předání prázdného slovníku jako globálního parametru

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

Výstup

 ('__builtins__') Traceback (poslední volání poslední): Soubor "", řádek 5, v tisku (eval ('sqrt (25)', ())) Soubor "", řádek 1, v NameError: název 'sqrt' není definován

Pokud předáte prázdný slovník jako globály, __builtins__jsou k dispozici pouze expression(první parametr eval()).

I když jsme mathmodul importovali do výše uvedeného programu, výraz nemá přístup k žádným funkcím poskytovaným matematickým modulem.

Příklad 4: Zpřístupnění určitých metod

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

Výstup

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

Zde se výraz lze použít pouze sqrt()a pow()metody spolu s __builtins__.

Je také možné změnit název metody dostupné pro výraz podle vašeho přání:

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

Výstup

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

Ve výše uvedeném programu square_root()vypočítá druhou odmocninu pomocí sqrt(). Pokus o sqrt()přímé použití však vyvolá chybu.

Příklad 5: Omezení používání vestavěných modulů

Použití __builtins__výrazu můžete omezit následujícím způsobem:

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

3. Předání slovníku globálních i místních obyvatel

Potřebné funkce a proměnné můžete zpřístupnit pro použití předáním slovníku místních obyvatel. Například:

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

Výstup

 13.0

V tomto programu může mít výraz pouze sqrt()metodu a proměnnou a. Všechny ostatní metody a proměnné nejsou k dispozici.

Omezení použití eval()předáním globálních a místních slovníků zajistí, že váš kód bude zabezpečený, zejména pokud používáte eval()metodu poskytnutou uživatelem od uživatele .

Poznámka: Někdy eval()není zabezpečená ani při omezeném počtu jmen. Když je objekt a jeho metody zpřístupněny, lze udělat téměř cokoli. Jediným bezpečným způsobem je ověření vstupu uživatele.

Zajímavé články...