Python eval ()

Методът eval () анализира израза, предаден на този метод, и изпълнява python израз (код) в рамките на програмата.

С прости думи, eval()функцията изпълнява кода на python (който се предава като аргумент) в рамките на програмата.

Синтаксисът на eval()е:

 eval (израз, глобални = няма, местни = няма)

eval () Параметри

Най eval()функция отнема три параметъра:

  • израз - низът е анализиран и оценен като израз на Python
  • глобални (по избор) - речник
  • местни (по избор) - обект за картографиране. Речникът е стандартният и често използван тип картографиране в Python.

Използването на глобални и местни жители ще бъде обсъдено по-нататък в тази статия.

Върната стойност от eval ()

Методът eval () връща резултата, оценен от израза.

Пример 1: Как eval () работи в Python

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

Изход

 2

Тук eval()функцията оценява израза x + 1и printсе използва за показване на тази стойност.

Пример 2: Практически пример за демонстриране на използването на 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

Изход

 Въведете функция: изчисли площ (l) Ако дължината е 1, Площ = 1 Ако дължината е 2, Площ = 4 Ако дължината е 3, Площ = 9 Ако дължината е 4, Площ = 16

Предупреждения при използване на eval ()

Помислете за ситуация, при която използвате система Unix (macOS, Linux и т.н.) и сте импортирали osмодула. Модулът os осигурява преносим начин за използване на функционалностите на операционната система като четене или запис във файл.

Ако се позволи на потребителите да въведете стойност използване eval(input()), потребителят може да издава команди към промяна файл или дори изтриете всички файлове с помощта на командата: os.system('rm -rf *').

Ако използвате eval(input())в кода си, е добра идея да проверите кои променливи и методи потребителят може да използва. Можете да видите кои променливи и методи са на разположение, използвайки метода dir ().

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

Изход

('__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', ' asinh ',' atan ',' atan2 ',' atanh ',' ceil ',' гребен ',' copysign ',' cos ',' cosh ',' градуси ',' 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')

Ограничаване на използването на наличните методи и променливи в eval ()

По-често всички налични методи и променливи, използвани в израза (първи параметър към eval()), може да не са необходими или дори да имат дупка в сигурността. Може да се наложи да ограничите използването на тези методи и променливи за eval(). Можете да го направите, като предадете на eval()функцията параметри (речници) на незадължителни глобални и локални параметри .

1. Когато са пропуснати както глобални, така и местни параметри

Ако и двата параметъра са пропуснати (както в нашите по-ранни примери), изразът се изпълнява в текущия обхват. Можете да проверите наличните променливи и методи, като използвате следния код:

 print(eval('dir()')

2. Предаващ глобален параметър; параметърът locals е пропуснат

The globals and locals parameters (dictionaries) are used for global and local variables respectively. If the locals dictionary is omitted, it defaults to globals dictionary. Meaning, globals will be used for both global and local variables.

Note: You can check the current global and local dictionary in Python using globals() and locals() built-in methods respectively.

Example 3: Passing empty dictionary as globals parameter

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

Output

 ('__builtins__') Traceback (most recent call last): File "", line 5, in print(eval('sqrt(25)', ())) File "", line 1, in NameError: name 'sqrt' is not defined

If you pass an empty dictionary as globals, only the __builtins__ are available to expression (first parameter to the eval()).

Въпреки че сме импортирали mathмодула в горната програма, изразът не може да получи достъп до функциите, предоставени от математическия модул.

Пример 4: Предоставяне на определени методи

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

Изход

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

Тук изразът може да използва само sqrt()и pow()методите заедно с __builtins__.

Също така е възможно да промените името на метода, наличен за израза, според вашето желание:

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

Изход

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

В горната програма square_root()изчислява квадратния корен с помощта на sqrt(). Опитът за sqrt()директно използване обаче ще доведе до грешка.

Пример 5: Ограничаване на използването на вградени

Можете да ограничите използването на __builtins__в израза, както следва:

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

3. Преминаване както на глобален, така и на местен речник

Можете да направите необходимите функции и променливи достъпни за използване, като предадете речника на местните жители. Например:

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

Изход

 13.0

В тази програма изразът може да има само sqrt()метод и променлива a. Всички други методи и променливи са недостъпни.

Ограничаването на използването на eval()речници на глобални и местни речници ще направи кода ви сигурен, особено когато използвате въведеното от метода въвеждане от потребителя eval().

Забележка: Понякога eval()не е защитен дори с ограничени имена. Когато обектът и неговите методи станат достъпни, може да се направи почти всичко. Единственият сигурен начин е чрез валидиране на въведеното от потребителя.

Интересни статии...