Execute a Script in Python
- Execute a Python Script in Python
- Use of globals and locals
This article will talk about how we can use Python to execute yet another python script.
Execute a Python Script in Python
- object : The Python code in string or byte format
- globals : It is an optional argument. It is a dictionary and contains global functions and variables.
- locals : It is an optional argument. It is a dictionary and contains local functions and variables.
Refer to the following code for an example.
file_name = "code.py" content = open(file_name).read() exec(content)
The above code first opens a file in the working directory by the name of code.py , reads its content, stores it inside a variable by the name content , and then passes the read content to the exec() function. The read content is some Python code, and the exec() method will execute that Python code.
If we have some local or global variables, we can store them inside dictionaries and pass them to the executable script. The script will then be able to utilize those variables and run the code. Note that if we use some functions inside the executable script that we have not passed as a global variable, the main program will throw an Exception.
The following code depicts the same.
from random import randint code = "print(randint(1, 6))" exec(code, <>, <>) # Empty globals and locals
Traceback (most recent call last): File "", line 4, in module> File "", line 1, in module> NameError: name 'randint' is not defined
When the globals and locals are not passed to the exec() , the requirements (to run the script) are automatically handled. Python is smart enough to figure out what all variables or functions are needed to run the script. For example, the following code will run perfectly without any error.
from random import randint code = "print(randint(1, 6))" exec(code) # No globals or locals passed
Use of globals and locals
We can create custom functions and imported functions inside the executable script by passing them to the exec() function via globals . As mentioned above, if these dependencies are not found, exceptions will be raised.
Refer to the following code. Here we will define a custom function and import a function from the random package. Then both functions will be passed to the exec() function wrapped inside a dictionary via the globals parameter.
from random import randint def get_my_age(): return 19 globals = "randint": randint, "get_my_age": get_my_age > code = """ print(randint(1, 6)) print(get_my_age()) """ exec(code, globals,)
5 # It can be any number between 1 and 6, both inclusive 19
Right now, these functions have been passed via the globals parameter. We can also pass them through locals . Since the exec function doesn’t accept keyword arguments, we have to pass an empty dictionary for globals and the pass out locals .
from random import randint def get_my_age(): return 19 locals = "randint": randint, "get_my_age": get_my_age > code = """ print(randint(1, 6)) print(get_my_age()) """ exec(code, <>, locals)
2 # It can be any number between 1 and 6, both inclusive 19
Vaibhav is an artificial intelligence and cloud computing stan. He likes to build end-to-end full-stack web and mobile applications. Besides computer science and technology, he loves playing cricket and badminton, going on bike rides, and doodling.
Метод exec() в Python
По сути, метод Python exec() выполняет переданный набор кода в виде строки. Это очень полезно, так как практически поддерживает динамическое выполнение. Синтаксис метода приведен ниже.
exec(object, globals, locals)
Здесь object может быть строкой, объектом открытого файла или объектом кода.
- Для строки — строка анализируется как набор операторов Python, который затем выполняется (если не возникает синтаксическая ошибка).
- Для открытого файла — файл анализируется до EOF и выполняется.
- Для объекта кода — просто выполняется.
И два дополнительных аргументов globals и locals должны быть словари , используемые для глобальных и локальных переменных.
Давайте попробуем понять, как он работает, на примере.
>>> exec("print('Hey!')") Hey! >>> exec("print(6+4)") 10
Из приведенного выше фрагмента кода ясно, что операторы print() успешно выполняются методом exec() и мы получаем желаемые результаты.
Работа с методом Python exec()
Теперь давайте сразу перейдем к некоторым примерам, изучающим, как метод exec() работает в Python с параметрами globals и locals и без них.
1 Без глобальных и локальных параметров
В предыдущем примере мы просто выполнили некоторый набор инструкций в Python, передав аргумент объекта методу exec() . Но мы не видели имена в текущей области.
Теперь давайте воспользуемся методом dir(), чтобы получить список текущих методов и имен с включенным math модулем перед вызовом метода exec() .
from math import * exec("print(pow(2, 5))") exec("print(dir())")
32.0 ['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'nan', 'pi', 'pow', 'radians', 'remainder', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'tau', 'trunc']
Как видите, различные методы, включая builtins , а также из math модуля, прямо сейчас находятся в текущей области видимости и доступны для метода exec() .
Это создает большую проблему безопасности, когда вы думаете о выполнении динамического кода Python. Пользователь может включать некоторые модули для доступа к системным командам, которые даже могут привести к сбою вашего компьютера.
Используя параметры globals и locals мы можем буквально ограничить exec() чтобы выйти за пределы методов, к которым мы хотим получить доступ.
2 С параметром globals
Python позволяет нам передавать и указывать только те методы, к которым мы хотим, чтобы метод exec() имел доступ (в форме словаря) из встроенного модуля.
def squareNo(a): return a*a exec('print(squareit(10))',>) exec("print(dir())")
100 ['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'squareNo']
В приведенном выше коде мы передали словарь, содержащий методы squareNo() (сопоставленные с настраиваемым именем squareit) и print() .
Обратите внимание: использование любого другого метода из встроенного метода вызовет TypeError .
3 С параметром locals
Когда мы передаем только local параметр (словарь), по умолчанию все встроенные методы также становятся доступными до тех пор, пока мы явно не исключим их.
Посмотрите на пример ниже, хотя мы указали словарь locals все встроенные и математические методы модуля доступны в текущей области.
from math import * def squareNo(a): return a*a #global And local parameters exec('print(pow(4,3))', ) exec("print(dir())")
64 ['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'nan', 'pi', 'pow', 'radians', 'remainder', 'sin', 'sinh', 'sqrt', 'squareNo', 'tan', 'tanh', 'tau', 'trunc']
Следовательно, теперь явно исключая встроенные функции.
from math import * def squareNo(a): return a*a #explicitly excluding built-ins exec('print(pow(4,3))', ,) exec("print(dir())")
Traceback (most recent call last): File "C:/Users/sneha/Desktop/test.py", line 7, in exec('print(pow(4,3))', ,) File "", line 1, in TypeError: 'NoneType' object is not subscriptable
В приведенном выше коде ограничение метода на использование только переданных (локальных) методов практически делает недоступным метод pow() . Следовательно, при его запуске мы получаем TypeError .
exec() сравнение с eval()
Между методами eval() и exec() есть два основных различия, хотя они выполняют почти одинаковую работу.
- eval() может выполнять только одно выражение, тогда как exec() может использоваться для выполнения динамически созданного оператора или программы, которая может включать циклы, операторы if-else , определения функций и class ,
- eval() возвращает значение после выполнения определенного выражения, тогда как exec() в основном ничего не возвращает и просто игнорирует значение.