Python exec ()

Метод exec () виконує динамічно створену програму, яка є або рядком, або об'єктом коду.

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

 exec (об'єкт, глобальні організації, місцеві жителі)

параметри exec ()

exec() приймає три параметри:

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

Про використання глобалів та місцевих жителів піде мова далі в статті.

Повернене значення з exec ()

exec()не повертає жодного значення, воно повертає None.

Приклад 1: Як працює exec ()?

 program = 'a = 5b=10print("Sum =", a+b)' exec(program)

Вихідні дані

 Сума = 15

Тут передається рядова об'єктна програма, до exec()якої виконується програма. глобали та місцеві жителі в цьому випадку опущені.

Приклад 2: Дозволити користувачеві вводити дані

  program = input('Enter a program:') exec(program) 

Вихідні дані

 Введіть програму: (надрукуйте (елемент) для елемента в (1, 2, 3)) 1 2 3

Якщо ви хочете взяти код Python у користувача, який дозволяє багаторядковий код (за допомогою ''), ви можете використовувати compile()метод перед використанням exec().

Дізнайтеся більше про метод compile () у Python.

Будьте обережні під час використання exec ()

Розглянемо ситуацію: ви використовуєте систему Unix (macOS, Linux тощо) і імпортували osмодуль. Модуль os забезпечує портативний спосіб використання функціональних можливостей операційної системи, таких як читання або запис файлу.

Якщо ви дозволяєте користувачам вводити значення за допомогою exec(input()), користувач може видавати команди на зміну файлу або навіть видаляти всі файли за допомогою команди os.system('rm -rf *').

Якщо ви використовуєте exec(input())свій код, корисно перевірити, які змінні та методи може використовувати користувач. Ви можете побачити, які змінні та методи доступні, використовуючи метод dir ().

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

Вихідні дані

('Вхід', 'Вихід', '_', '__', '___', '__builtin__', '__builtins__', '__name__', '_dh', '_i', '_i1', '_i2', ' _ih ',' _ii ',' _iii ',' _oh ',' _sh ',' acos ',' acosh ',' asin ',' asinh ',' atan ',' atan2 ',' atanh ',' ceil ' , 'copysign', 'cos', 'cosh', 'градуси', '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 ',' radians ',' sin ',' sinh ' , 'sqrt', 'tan', 'tanh', 'trunc')

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

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

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

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

 exec ('print (dir ())')

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

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

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

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

 from math import * exec('print(dir())', ()) # This code will raise an exception # exec('print(sqrt(9))', ())

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

Вихідні дані

 ('__builtins__')

Надання певних методів

 from math import * exec('print(dir())', ('sqrt': sqrt, 'pow': pow)) # object can have sqrt() module exec('print(sqrt(9))', ('sqrt': sqrt, 'pow': pow))

Тут код, який виконується за допомогою exec (), також може мати sqrt()і pow()методи, а також __builtins__.

Можна змінити назву методу відповідно до вашого бажання.

 from math import * exec('print(dir())', ('squareRoot': sqrt, 'pow': pow)) # object can have squareRoot() module exec('print(squareRoot(9))', ('squareRoot': sqrt, 'pow': pow))

У наведеній вище програмі squareRoot()обчислює квадратний корінь (аналогічна функціональності, як sqrt()). Однак спроба використання sqrt()спричинить виняток.

Обмеження використання вбудованих програм

Ви можете обмежити використання __builtins__даючи значення Noneдо '__builtins__'в словнику глобал.

 exec (об'єкт, ('__builtins__': немає)) 

4. Передача словника як глобальних, так і місцевих

Ви можете зробити необхідні функції та змінні доступними для використання, передавши словник місцевих жителів. Наприклад:

 from math import * globalsParameter = ('__builtins__' : None) localsParameter = ('print': print, 'dir': dir) exec('print(dir())', globalsParameter, localsParameter)

Вихідні дані

 ('dir', 'print') 

Тут лише два вбудовані методи print () і dir () можуть бути виконані exec()методом.

Важливо зазначити, що, exec()виконує код і не повертає жодного значення (повертається None). Отже, ви не можете використовувати оператори return і yield поза визначенням функції.

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