Python exec ()

Методът 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 извън дефинициите на функциите.

Интересни статии...