Метод exec () выполняет динамически созданную программу, которая представляет собой строку или объект кода.
Синтаксис exec()
:
exec (объект, глобальные, локальные)
Параметры exec ()
exec()
принимает три параметра:
- объект - Либо строка, либо объект кода
- globals (необязательно) - словарь
- locals (необязательно) - объект отображения. Словарь - это стандартный и часто используемый тип сопоставления в Python.
Об использовании глобальных и локальных переменных мы поговорим позже в статье.
Возвращаемое значение из exec ()
exec()
не возвращает никакого значения, он возвращается None
.
Пример 1: Как работает exec ()?
program = 'a = 5b=10print("Sum =", a+b)' exec(program)
Вывод
Сумма = 15
Здесь передается программа строкового объекта, exec()
которая выполняет программу. globals и locals в этом случае опускаются.
Пример 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())')
Вывод
('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', 'степени', '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 ',' радианы ',' sin ',' sinh ' , 'sqrt', 'tan', 'tanh', 'trunc')
Ограничение использования доступных методов и переменных в exec ()
Чаще всего все доступные методы и переменные, используемые в, exec()
могут не понадобиться или даже могут иметь брешь в безопасности. Вы можете ограничить использование этих переменных и методов, передав в exec()
метод необязательные глобальные и локальные параметры (словари) .
1. Параметры globals и locals опущены.
Если оба параметра опущены (как в наших предыдущих примерах), код, который должен быть выполнен, exec()
выполняется в текущей области. Вы можете проверить доступные переменные и методы, используя следующий код:
exec ('печать (каталог ())')
2. Передача глобальных параметров; параметр locals опущен
Параметры globals и locals (словари) используются для глобальных и локальных переменных соответственно. Если словарь locals опущен, по умолчанию используется словарь globals. Это означает, что глобальные переменные будут использоваться как для глобальных, так и для локальных переменных.
Примечание. Вы можете проверить текущий глобальный и локальный словарь в Python, используя встроенные методы globals () и locals () соответственно.
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))
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')
Здесь только два встроенных метода print () и dir () могут быть выполнены exec()
методом.
Важно отметить, что exec()
выполняет код и не возвращает никакого значения (возвращает None
). Следовательно, вы не можете использовать операторы return и yield вне определений функций.