Python exec ()

Metoda exec () wykonuje dynamicznie utworzony program, który jest ciągiem znaków lub obiektem kodu.

Składnia exec():

 exec (obiekt, globals, locals)

exec () Parametry

exec() przyjmuje trzy parametry:

  • obiekt - ciąg znaków lub obiekt kodu
  • globals (opcjonalnie) - słownik
  • locals (opcjonalnie) - obiekt mapujący. Słownik to standardowy i powszechnie używany typ mapowania w Pythonie.

Użycie zmiennych globalnych i lokalnych zostanie omówione w dalszej części artykułu.

Wartość zwracana z exec ()

exec()nie zwraca żadnej wartości, zwraca None.

Przykład 1: Jak działa exec ()?

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

Wynik

 Suma = 15

Tutaj przekazywany jest program będący obiektem łańcucha, do exec()którego program jest wykonywany. W tym przypadku pomijane są wartości globalne i lokalne.

Przykład 2: Pozwól użytkownikowi wprowadzić dane wejściowe

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

Wynik

 Wprowadź program: (drukuj (element) dla pozycji w (1, 2, 3)) 1 2 3

Jeśli chcesz pobrać kod Pythona od użytkownika, który zezwala na kod wielowierszowy (przy użyciu ''), możesz użyć compile()metody przed użyciem exec().

Dowiedz się więcej o metodzie compile () w Pythonie.

Uważaj podczas używania exec ()

Rozważ sytuację, gdy używasz systemu Unix (macOS, Linux itp.) I zaimportowałeś osmoduł. Moduł os zapewnia przenośny sposób korzystania z funkcji systemu operacyjnego, takich jak odczyt lub zapis pliku.

Jeśli zezwolisz użytkownikom na wprowadzanie wartości za pomocą exec(input()), użytkownik może wydawać polecenia zmiany pliku lub nawet usunąć wszystkie pliki za pomocą polecenia os.system('rm -rf *').

Jeśli używasz exec(input())w swoim kodzie, dobrym pomysłem jest sprawdzenie, których zmiennych i metod może używać użytkownik. Możesz zobaczyć, które zmienne i metody są dostępne za pomocą metody dir ().

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

Wynik

(„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”, „stopnie”, „e”, „erf”, „erfc”, „wyjście”, „exp”, „expm1”, „fabs”, „silnia”, „ 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”)

Ograniczanie użycia dostępnych metod i zmiennych w exec ()

Najczęściej wszystkie dostępne metody i zmienne używane w programie exec()mogą nie być potrzebne, a nawet mogą mieć lukę w zabezpieczeniach. Możesz ograniczyć użycie tych zmiennych i metod, przekazując opcjonalne parametry globalne i lokalne (słowniki) do exec()metody.

1. Pomijane są zarówno parametry globalne, jak i lokalne

Jeśli oba parametry zostaną pominięte (jak we wcześniejszych przykładach), kod, który ma zostać wykonany przez, exec()jest wykonywany w bieżącym zakresie. Możesz sprawdzić dostępne zmienne i metody za pomocą następującego kodu:

 exec ('print (dir ())')

2. Przekazywanie parametru globals; parametr locals jest pominięty

Parametry globalne i lokalne (słowniki) są używane odpowiednio dla zmiennych globalnych i lokalnych. Jeśli pominięto słownik lokalny, domyślnie jest to słownik globalny. Oznacza to, że wartości globalne będą używane zarówno dla zmiennych globalnych, jak i lokalnych.

Uwaga: Możesz sprawdzić bieżący słownik globalny i lokalny w Pythonie, używając odpowiednio wbudowanych metod globals () i locals ().

3. Podanie pustego słownika jako parametru globalnego

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

Jeśli przekażesz pusty słownik jako globals, tylko __builtins__są dostępne dla object(pierwszego parametru funkcji exec ()). Mimo że zaimportowaliśmy moduł matematyczny do powyższego programu, próba uzyskania dostępu do którejkolwiek z funkcji udostępnianych przez moduł matematyczny spowoduje zgłoszenie wyjątku.

Wynik

 („__builtins__”)

Udostępnianie określonych metod

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

Tutaj tylko dwie wbudowane metody print () i dir () mogą być wykonane przy użyciu exec()metody.

Należy pamiętać, że exec()wykonuje kod i nie zwraca żadnej wartości (zwraca None). Dlatego nie można używać instrukcji return i yield poza definicjami funkcji.

Interesujące artykuły...