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ś os
moduł. 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.