Exec () -menetelmä suorittaa dynaamisesti luodun ohjelman, joka on joko merkkijono tai koodiobjekti.
Syntaksi exec()
:
exec (esine, globaalit, paikalliset)
exec () -parametrit
exec()
ottaa kolme parametria:
- object - joko merkkijono tai koodiobjekti
- globaalit (valinnainen) - sanakirja
- paikalliset (valinnainen) - kartoitusobjekti. Sanakirja on tavallinen ja yleisesti käytetty kartoitustyyppi Pythonissa.
Globaalien ja paikallisten käytöstä keskustellaan myöhemmin artikkelissa.
Palautusarvo exec: ltä ()
exec()
ei palauta arvoa, se palauttaa None
.
Esimerkki 1: Kuinka exec () toimii?
program = 'a = 5b=10print("Sum =", a+b)' exec(program)
Tuotos
Summa = 15
Tässä välitetään merkkijono-ohjelma, exec()
joka suorittaa ohjelman. globaalit ja paikalliset jätetään tässä tapauksessa pois.
Esimerkki 2: Anna käyttäjän antaa syötettä
program = input('Enter a program:') exec(program)
Tuotos
Syötä ohjelma: (tulosta (kohde) kohteelle (1, 2, 3)) 1 2 3
Jos haluat ottaa käyttäjältä Python-koodin, joka sallii monirivisen koodin (käyttäen ''
), voit käyttää compile()
menetelmää ennen käyttöä exec()
.
Lisätietoja compile () -menetelmästä Pythonissa.
Ole varovainen käyttäessäsi exec ()
Harkitse tilannetta, käytät Unix-järjestelmää (macOS, Linux jne.) Ja olet tuonut os
moduulin. OS-moduuli tarjoaa kannettavan tavan käyttää käyttöjärjestelmän toimintoja, kuten lukea tai kirjoittaa tiedostoa.
Jos annat käyttäjien syöttää arvon käyttämällä exec(input())
, käyttäjä voi antaa komentoja tiedoston muuttamiseksi tai jopa poistaa kaikki tiedostot komennolla os.system('rm -rf *')
.
Jos käytät exec(input())
koodissasi, on hyvä tarkistaa, mitä muuttujia ja menetelmiä käyttäjä voi käyttää. Dir () -menetelmällä näet, mitkä muuttujat ja menetelmät ovat käytettävissä.
from math import * exec('print(dir())')
Tuotos
('Sisään', 'Ulos', '_', '__', '___', '__builtin__', '__builtins__', '__nimi__', '_dh', '_i', '_i1', '_i2', ' _ih ',' _ii ',' _iii ',' _oh ',' _sh ',' acos ',' acosh ',' asin ',' asinh ',' atan ',' atan2 ',' atanh ',' katto ' , 'copysign', 'cos', 'cosh', 'astetta', 'e', 'erf', 'erfc', 'exit', 'exp', 'expm1', 'fabs', 'factororial', ' lattia ',' 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')
Käytettävissä olevien menetelmien ja muuttujien käytön rajoittaminen execissä ()
Useimmiten kaikkia käytettävissä olevia menetelmiä ja muuttujia, joita käytetään, exec()
ei ehkä tarvita, tai niillä voi jopa olla turva-aukko. Voit rajoittaa näiden muuttujien ja menetelmien käyttöä siirtämällä valinnaiset globaalit ja paikalliset parametrit (sanakirjat) exec()
menetelmään.
1. Sekä globaalit että paikalliset parametrit jätetään pois
Jos molemmat parametrit jätetään pois (kuten aikaisemmissa esimerkeissämme), koodi, jonka odotetaan suorittavan, exec()
suoritetaan nykyisessä laajuudessa. Voit tarkistaa käytettävissä olevat muuttujat ja menetelmät seuraavalla koodilla:
exec ('tulosta (dir ())')
2. Passivaava globaali parametri; localals-parametri jätetään pois
Globaalia ja paikallista parametria (sanakirjoja) käytetään vastaavasti globaaleihin ja paikallisiin muuttujiin. Jos paikallisten sanakirja jätetään pois, se on oletuksena maailmanlaajuinen sanakirja. Merkitys, globaaleja käytetään sekä globaaleihin että paikallisiin muuttujiin.
Huomautus: Voit tarkistaa nykyisen yleisen ja paikallisen sanakirjan Pythonissa käyttämällä sisäänrakennettuja globaaleja () ja paikallisia () menetelmiä.
3. Tyhjän sanakirjan välittäminen globaalina parametrina
from math import * exec('print(dir())', ()) # This code will raise an exception # exec('print(sqrt(9))', ())
Jos välität tyhjän sanakirjan globaaleina, vain ne __builtins__
ovat käytettävissä object
(exec: n ensimmäinen parametri ()). Vaikka olemme tuoneet matematiikkamoduulia yllä olevaan ohjelmaan, yrittää käyttää mitä tahansa matematiikkamoduulin tarjoamista toiminnoista aiheuttaa poikkeuksen.
Tuotos
('__builtins__')
Tiettyjen menetelmien asettaminen saataville
from math import * exec('print(dir())', ('sqrt': sqrt, 'pow': pow)) # object can have sqrt() module exec('print(sqrt(9))', ('sqrt': sqrt, 'pow': pow))
Tässä myös exec (): n suorittama koodi voi olla sqrt()
ja pow()
menetelmät yhdessä __builtins__
.
Menetelmän nimi on mahdollista vaihtaa toiveesi mukaan.
from math import * exec('print(dir())', ('squareRoot': sqrt, 'pow': pow)) # object can have squareRoot() module exec('print(squareRoot(9))', ('squareRoot': sqrt, 'pow': pow))
squareRoot()
Laskee edellisessä ohjelmassa neliöjuuren (samanlainen toiminto kuin sqrt()
). Käyttöyritys kuitenkin sqrt()
aiheuttaa poikkeuksen.
Sisäisten käyttöjen rajoittaminen
Voit rajoittaa käyttöä __builtins__
antamalla arvon None
kuin '__builtins__'
on global sanakirjassa.
exec (objekti, ('__builtins__': Ei mitään))
4. Sekä maailmanlaajuisten että paikallisten sanakirjan läpäisy
Voit asettaa tarvittavat toiminnot ja muuttujat käytettäväksi ohittamalla paikallisten sanakirjan. Esimerkiksi:
from math import * globalsParameter = ('__builtins__' : None) localsParameter = ('print': print, 'dir': dir) exec('print(dir())', globalsParameter, localsParameter)
Tuotos
('dir', 'print')
Tässä vain kaksi sisäänrakennettua menetelmää print () ja dir () voidaan suorittaa exec()
menetelmällä.
On tärkeää huomata, että exec()
suorittaa koodin eikä palauta arvoa (palauttaa None
). Siksi et voi käyttää return- ja return-lauseita funktion määritelmien ulkopuolella.