Python exec ()

O método exec () executa o programa criado dinamicamente, que é uma string ou um objeto de código.

A sintaxe de exec():

 exec (objeto, globais, locais)

Parâmetros exec ()

exec() leva três parâmetros:

  • object - uma string ou um objeto de código
  • globais (opcional) - um dicionário
  • locais (opcional) - um objeto de mapeamento. Dicionário é o tipo de mapeamento padrão e comumente usado em Python.

O uso de globais e locais será discutido posteriormente neste artigo.

Valor de retorno de exec ()

exec()não retorna nenhum valor, ele retorna None.

Exemplo 1: Como exec () funciona?

 program = 'a = 5b=10print("Sum =", a+b)' exec(program)

Resultado

 Soma = 15

Aqui, o programa do objeto string é passado para o exec()qual executa o programa. globais e locais são omitidos neste caso.

Exemplo 2: permitir que o usuário forneça dados

  program = input('Enter a program:') exec(program) 

Resultado

 Insira um programa: (imprimir (item) para o item em (1, 2, 3)) 1 2 3

Se você deseja obter o código Python do usuário que permite código multilinha (usando ''), pode usar o compile()método antes de usar exec().

Saiba mais sobre o método compile () em Python.

Tenha cuidado ao usar exec ()

Considere uma situação, você está usando um sistema Unix (macOS, Linux etc) e importou o osmódulo. O módulo os fornece uma maneira portátil de usar as funcionalidades do sistema operacional, como ler ou gravar um arquivo.

Se você permitir que os usuários insiram um valor usando exec(input()), o usuário pode emitir comandos para alterar o arquivo ou até mesmo excluir todos os arquivos usando o comando os.system('rm -rf *').

Se você estiver usando exec(input())em seu código, é uma boa ideia verificar quais variáveis ​​e métodos o usuário pode usar. Você pode ver quais variáveis ​​e métodos estão disponíveis usando o método dir ().

 from math import * exec('print(dir())')

Resultado

('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', 'degrees', 'e', ​​'erf', 'erfc', 'exit', 'exp', 'expm1', 'fabs', 'fatorial', ' floor ',' fmod ',' frexp ',' fsum ',' gamma ',' gcd ',' get_ipython ',' hypot ',' inf ',' isclose ',' isfinite ',' isinf ',' isnan ' , 'ldexp', 'lgamma ',' log ',' log10 ',' log1p ',' log2 ',' modf ',' nan ',' pi ',' pow ',' sair ',' radianos ',' sin ',' sinh ' , 'sqrt', 'tan', 'tanh', 'trunc')

Restringindo o uso de métodos e variáveis ​​disponíveis em exec ()

Na maioria das vezes, todos os métodos e variáveis ​​disponíveis usados ​​em exec()podem não ser necessários, ou mesmo podem ter uma falha de segurança. Você pode restringir o uso dessas variáveis ​​e métodos passando parâmetros opcionais globais e locais (dicionários) para o exec()método.

1. Os parâmetros globais e locais são omitidos

Se ambos os parâmetros forem omitidos (como em nossos exemplos anteriores), o código que se espera que seja executado por exec()é executado no escopo atual. Você pode verificar as variáveis ​​e métodos disponíveis usando o seguinte código:

 exec ('print (dir ())')

2. Passando parâmetro global; parâmetro locals é omitido

The globals and locals parameters (dictionaries) are used for global and local variables respectively. If locals dictionary is omitted, it defaults to globals dictionary. Meaning, globals will be used for both global and local variables.

Note: You can check the current global and local dictionary in Python using globals() and locals() built-in methods respectively.

3. Passing empty dictionary as globals parameter

 from math import * exec('print(dir())', ()) # This code will raise an exception # exec('print(sqrt(9))', ())

If you pass an empty dictionary as globals, only the __builtins__ are available to the object (first parameter to the exec()). Even though we have imported math module in the above program, trying to access any of the functions provided by the math module will raise an exception.

Output

 ('__builtins__')

Making Certain Methods available

 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') 

Aqui, apenas dois métodos internos print () e dir () podem ser executados pelo exec()método.

É importante notar que, exec()executa o código e não retorna nenhum valor (retorna None). Portanto, você não pode usar as instruções return e yield fora das definições da função.

Artigos interessantes...