English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Метод exec() выполняет динамически созданную программу, которая может быть строкой или объектом кода.
Синтаксис exec()
exec(object, globals, locals)
exec() принимает три параметра:
Объект -Строка или объект кода
globals (Дополнительное)-Словарь
locals(Дополнительное)-Объект карты. Словарь является одним из наиболее常用的 стандартных типов карт в Python.
Об этом будет рассказано позже в статьеГлобальные переменные(globals) и (locals)ЛокальныеПеременныеиспользование.
exec() не возвращает никакого значения, он возвращает None.
program = 'a = 5\nb=10\nprint("Sum =", a+b)' exec(program)
При запуске программы вывод будет следующим:
Sum = 15
Здесь строковый объект program передается в exec(), выполняющий эту программу. В данном примере опущены глобальные переменные (globals) и (locals)Локальные переменные.
program = input('Ввести программу:') exec(program)
При запуске программы вывод будет следующим:
Ввод программы: [print(item) for item in [1, 2, 3]] 1 2 3
Если нужно получить Python-код от пользователя, который может вводить многострочный код (используя '\n'), можно использовать метод compile() до использования exec().
Узнайте оМетод compile() в PythonБолее подробная информация.
Рассмотрим ситуацию, когда вы используете систему Unix (macOS, Linux и т.д.) и импортировали модуль os. Модуль os предоставляет портативные методы для использования функций операционной системы, например: чтение или запись файлов.
Если пользователи могут использовать exec(input()), чтобы вводить значения, пользователи могут отправить команды для изменения файлов, а также могут использовать command для удаления всех файлов 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', 'degrees', '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(), и даже могут быть уязвимости безопасности. Вы можете ограничить их использование, передав необходимыеglobalsиlocalsпараметры (словари) передаются в метод exec() для ограничения использования этих переменных и методов.
Если оба параметра пропущены (например, в наших предыдущих примерах), exec() ожидает выполнения кода в текущем диапазоне. Вы можете использовать следующий код для проверки доступных переменных и методов:
exec('print(dir())')
(globals) и (locals)параметр(словарь), отдельно для глобальных и локальных переменных. Если опущенlocalsСловарь, по умолчанию будетglobalsСловарь. Это означает, чтоГлобальные переменные (globals)Будет использоваться для глобальных и локальных переменных.
Примечание:Вы можете использовать их отдельноglobals()иlocals()Внутренние методы в Python проверяют текущий глобальный и локальный словари.
from math import * exec('print(dir())', {}) # Этот код вызовет исключение # exec('print(sqrt(9))', {})
Если передается пустой словарь какglobalsЕсли передается, то object (первый параметр exec()) может использовать только __builtins__. Даже если мы импортировали модуль math в aforementioned программе, попытка доступамодуль mathЛюбая функция, предоставленная, также вызовет исключение.
При запуске программы вывод будет следующим:
__builtins__
from math import * exec('print(dir())', {'sqrt': sqrt, 'pow': pow}) # Объект может иметь модуль sqrt() exec('print(sqrt(9))', {'sqrt': sqrt, 'pow': pow})
Здесь код, выполняемый exec(), также может иметь методы sqrt() и pow() и __builtins__.
Можете изменить имя метода по своему усмотрению.
from math import * exec('print(dir())', {'squareRoot': sqrt, 'pow': pow}) # Объект может иметь модуль squareRoot() exec('print(squareRoot(9))', {'squareRoot': sqrt, 'pow': pow})
В aforementioned программе squareRoot() вычисляет квадратный корень (аналогичные функции, такие как sqrt()). Однако попытка использования sqrt() вызовет исключение.
Вы можете ограничить использование __builtins__ путем присвоения None значению __builtins__ в словаре globals.
exec(object, {'__builtins__': None})
Вы можете передатьЛокальноИспользование словаря locals) для доступа к необходимым функциям и переменным. Например:
from math import * globalsParameter = {'__builtins__': None} localsParameter = {'print': print, 'dir': dir} exec('print(dir())', globalsParameter, localsParameter)
При запуске программы вывод будет следующим:
['dir', 'print']
Здесь exec() метод может выполнять только два встроенных методаprint()иdir().
Особое внимание следует уделять тому, что exec() выполняет код и не возвращает никаких значений (возвращает None). Поэтому вы не можете использовать return вне определения функции иyieldвыражение.