Методът exec () изпълнява динамично създадената програма, която е или низ, или кодов обект.
Синтаксисът на exec()
:
exec (обект, глобални, местни)
exec () Параметри
exec()
отнема три параметъра:
- обект - или низ, или кодов обект
- глобални (по избор) - речник
- местни (по избор) - обект за картографиране. Речникът е стандартният и често използван тип картографиране в 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())')
Изход
('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', ' етаж ',' fmod ',' frexp ',' fsum ',' гама ',' 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. Предаващ глобален параметър; параметърът locals е пропуснат
Глобалните и локалните параметри (речници) се използват съответно за глобални и локални променливи. Ако местният речник е пропуснат, той по подразбиране е глобален речник. Това означава, че глобалите ще бъдат използвани както за глобални, така и за локални променливи.
Забележка: Можете да проверите текущия глобален и локален речник в Python, използвайки съответно вградени методи globals () и local ().
3. Предаване на празен речник като глобален параметър
from math import * exec('print(dir())', ()) # This code will raise an exception # exec('print(sqrt(9))', ())
Ако предавате празен речник като глобални, само (на първия параметър на exec ()) __builtins__
са достъпни само те object
. Въпреки че сме импортирали математически модул в горната програма, опитът за достъп до някоя от функциите, предоставени от математическия модул, ще доведе до изключение.
Изход
('__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 извън дефинициите на функциите.