Python eval ()

Метод eval () аналізує вираз, переданий цьому методу, і запускає вираз python (код) у програмі.

Простіше кажучи, eval()функція запускає код програми python (який передається як аргумент) всередині програми.

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

 eval (вираз, глобальні = Немає, місцеві = Немає)

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

eval()Функція приймає три параметри:

  • вираз - рядок, проаналізований і оцінений як вираз Python
  • globals (за бажанням) - словник
  • місцеві жителі (за бажанням) - об’єкт картографування. Словник - це стандартний і часто використовуваний тип відображення в 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

Вихідні дані

 Введіть функцію: calcuArea (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()'))

Вихідні дані

('__нотації__', '__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 ',' ostatak ',' sin ',' sinh ',' sqrt ' , 'tan', 'tanh', 'tau', 'trunc')

Обмеження використання доступних методів та змінних у eval ()

Найчастіше всі доступні методи та змінні, що використовуються у виразі (перший параметр до eval()), можуть не знадобитися або навіть мати дірку в безпеці. Можливо, вам доведеться обмежити використання цих методів та змінних для eval(). Ви можете зробити це, передавши функції додаткові глобальні та локальні параметри (словники) eval().

1. Коли параметри як глобальних, так і місцевих опущені

Якщо обидва параметри опущені (як у наших попередніх прикладах), вираз виконується в поточній області. Ви можете перевірити доступні змінні та методи, використовуючи такий код:

 print(eval('dir()')

2. Передача глобального параметра; Місцевий параметр опущений

Глобальні та локальні параметри (словники) використовуються для глобальних та локальних змінних відповідно. Якщо словник місцевих жителів опущений, це стандартний словник. Це означає, що глобальні дані будуть використовуватися як для глобальних, так і для локальних змінних.

Примітка: Ви можете перевірити поточний глобальний та локальний словник на Python, використовуючи вбудовані методи globals () та local ().

Приклад 3: Передача порожнього словника як глобального параметра

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

Вихідні дані

 ('__builtins__') Відстеження (останній останній дзвінок): Файл "", рядок 5, надрукований (eval ('sqrt (25)', ())) Файл "", рядок 1, у NameError: name 'sqrt' не визначено

Якщо ви передаєте порожній словник як глобальний, __builtins__доступні лише expression(перший параметр до 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()це не захищено навіть з обмеженими іменами. Коли об’єкт та його методи стають доступними, можна зробити майже все. Єдиний безпечний спосіб - це перевірка введення користувачем.

Цікаві статті...