Metóda exec () vykoná dynamicky vytvorený program, ktorým je buď reťazec, alebo kódový objekt.
Syntax exec()
:
exec (objekt, globáli, miestni obyvatelia)
Parametre exec ()
exec()
má tri parametre:
- objekt - buď reťazec, alebo kódový objekt
- globály (voliteľné) - slovník
- locals (voliteľné) - mapovací objekt. Slovník je štandardný a bežne používaný typ mapovania v Pythone.
O použití globálov a miestnych obyvateľov sa bude diskutovať ďalej v článku.
Vrátená hodnota z exec ()
exec()
nevráti žiadnu hodnotu, vráti sa None
.
Príklad 1: Ako funguje exec ()?
program = 'a = 5b=10print("Sum =", a+b)' exec(program)
Výkon
Súčet = 15
Tu sa odovzdá program s reťazcovými objektmi, ktorý program exec()
vykoná. globáli a miestni obyvatelia sú v tomto prípade vynechaní.
Príklad 2: Umožniť používateľovi poskytnúť vstup
program = input('Enter a program:') exec(program)
Výkon
Zadajte program: (tlač (položka) pre položku v (1, 2, 3)) 1 2 3
Ak chcete prevziať kód Python od používateľa, ktorý umožňuje viacriadkový kód (pomocou ''
), môžete compile()
pred použitím použiť metódu exec()
.
Získajte viac informácií o metóde compile () v Pythone.
Pri používaní exec () buďte opatrní
Zvážte situáciu, že používate unixový systém (macOS, Linux atď.) A importovali ste os
modul. Modul os poskytuje prenosný spôsob, ako používať funkcie operačného systému, ako je čítanie alebo zápis súboru.
Ak povolíte používateľom zadať hodnotu pomocou exec(input())
, užívateľ môže vydať príkazy na zmenu súboru alebo dokonca vymazanie všetkých súborov pomocou príkazu os.system('rm -rf *')
.
Ak exec(input())
vo svojom kóde používate, je dobré skontrolovať, ktoré premenné a metódy môže používateľ použiť. Pomocou metódy dir () môžete zistiť, ktoré premenné a metódy sú k dispozícii.
from math import * exec('print(dir())')
Výkon
('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“, „stupne“, „e“, „erf“, „erfc“, „výstup“, „exp“, „expm1“, „fabs“, „faktoriál“, „ 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 ',' radiány ',' sin ',' sinh ' , 'sqrt', 'tan', 'tanh', 'trunc')
Obmedzenie používania dostupných metód a premenných v exec ()
Častejšie exec()
nemusí byť potrebné použiť všetky dostupné metódy a premenné, ktoré môžu byť použité, alebo dokonca môžu mať bezpečnostnú dieru. Používanie týchto premenných a metód môžete obmedziť odovzdaním voliteľných globálnych a miestnych parametrov (slovníkov) exec()
metóde.
1. Globálne aj miestne parametre sú vynechané
Ak sú oba parametre vynechané (ako v našich predchádzajúcich príkladoch), kód, ktorý sa má vykonať, exec()
sa vykoná v aktuálnom rozsahu. Dostupné premenné a metódy môžete skontrolovať pomocou nasledujúceho kódu:
exec ('print (dir ())')
2. Passing globals parameter; parameter locals je vynechaný
Parametre globals a locals (slovníky) sa používajú pre globálne a lokálne premenné. Ak je slovník miestnych obyvateľov vynechaný, použije sa predvolený slovník globálov. To znamená, že globálne budú použité pre globálne aj lokálne premenné.
Poznámka: Aktuálny globálny a lokálny slovník v Pythone môžete skontrolovať pomocou vstavaných metód globals () a locals ().
3. Odovzdanie prázdneho slovníka ako parametra globálov
from math import * exec('print(dir())', ()) # This code will raise an exception # exec('print(sqrt(9))', ())
Ak odovzdáte prázdny slovník ako globály, k __builtins__
dispozícii sú iba tie object
(prvý parameter pre exec ()). Aj keď sme do vyššie uvedeného programu importovali matematický modul, pokus o prístup k niektorej z funkcií poskytovaných matematickým modulom vyvolá výnimku.
Výkon
('__builtins__')
Sprístupnenie určitých metód
from math import * exec('print(dir())', ('sqrt': sqrt, 'pow': pow)) # object can have sqrt() module exec('print(sqrt(9))', ('sqrt': sqrt, 'pow': pow))
Tu je kód, ktorý sa vykonáva pomocou exec () môže mať tiež sqrt()
aj pow()
metódy spolu s __builtins__
.
Je možné zmeniť názov metódy podľa vášho želania.
from math import * exec('print(dir())', ('squareRoot': sqrt, 'pow': pow)) # object can have squareRoot() module exec('print(squareRoot(9))', ('squareRoot': sqrt, 'pow': pow))
Vo vyššie uvedenom programe sa squareRoot()
vypočíta druhá odmocnina (podobná funkcionalita sqrt()
). Pokus o použitie sqrt()
však vyvolá výnimku.
Obmedzenie používania vstavaných zariadení
Môžete obmedziť používanie __builtins__
tým, že hodnoty None
na '__builtins__'
v Globals slovníka.
exec (objekt, ('__builtins__': žiadny))
4. Absolvovanie slovníka globálnych aj miestnych obyvateľov
Potrebné funkcie a premenné môžete sprístupniť na použitie odovzdaním slovníka miestnych obyvateľov. Napríklad:
from math import * globalsParameter = ('__builtins__' : None) localsParameter = ('print': print, 'dir': dir) exec('print(dir())', globalsParameter, localsParameter)
Výkon
('dir', 'print')
Tu je možné exec()
metódou vykonať iba dve zabudované metódy print () a dir () .
Je dôležité si uvedomiť, že exec()
vykoná kód a nevráti žiadnu hodnotu (vráti None
). Preto nemôžete používať výkazy návratov a výnosov mimo definícií funkcií.