Sök…


Syntax

  • eval (uttryck [, globaler = Inget [, lokalbefolkningen = Inget]])
  • exec (objekt)
  • exec (objekt, globaler)
  • exec (objekt, globaler, lokalbefolkningen)

parametrar

Argument detaljer
expression Uttrycket koden som en sträng, eller en code -objekt
object Uttalandet kod som en sträng, eller en code objekt
globals Ordboken som ska användas för globala variabler. Om lokalbefolkningen inte anges används den också för lokalbefolkningen. Om de utelämnas används de globals() av samtalsomfånget.
locals Ett mappningsobjekt som används för lokala variabler. Om den utelämnas används den som skickas för globals istället. Om båda utelämnas används globals() och locals() i samtalsområdet för globals respektive locals .

Anmärkningar

I exec , om globals är locals (dvs. de hänvisar till samma objekt), körs koden som om den är på modulnivå. Om globals och locals är distinkta objekt körs koden som om den var i en klasskropp .

Om globals skickas in, men inte anger __builtins__ tangenten, __builtins__ Python inbyggda funktioner och namn automatiskt till det globala omfånget. För att undertrycka tillgängligheten för funktioner som print eller isinstance i det exekverade omfånget, låt globals ha nyckeln __builtins__ mappad till värdet None . Detta är dock inte en säkerhetsfunktion.

Python 2-specifik syntax bör inte användas; Python 3-syntaxen fungerar i Python 2. Följaktligen avskrivs följande former: <s>

  • exec object
  • exec object in globals
  • exec object in globals, locals

Utvärdera uttalanden med exec

>>> code = """for i in range(5):\n    print('Hello world!')"""
>>> exec(code)
Hello world!
Hello world!
Hello world!
Hello world!
Hello world!

Utvärdera ett uttryck med eval

>>> expression = '5 + 3 * a'
>>> a = 5
>>> result = eval(expression)
>>> result
20

Förkompilera ett uttryck för att utvärdera det flera gånger

compile inbyggd funktion kan användas för att kompilera ett uttryck till ett kodobjekt; detta kodobjekt kan sedan överföras till eval. Detta påskyndar de upprepade körningarna av den utvärderade koden. Den tredje parametern som ska compile måste vara strängen 'eval' .

>>> code = compile('a * b + c', '<string>', 'eval')
>>> code
<code object <module> at 0x7f0e51a58830, file "<string>", line 1>
>>> a, b, c = 1, 2, 3
>>> eval(code)
5

Utvärdera ett uttryck med eval med hjälp av anpassade globaler

>>> variables = {'a': 6, 'b': 7}
>>> eval('a * b', globals=variables)
42

Som ett plus kan koden inte av misstag hänvisa till namnen definierade utanför:

>>> eval('variables')
{'a': 6, 'b': 7}
>>> eval('variables', globals=variables)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1, in <module>
NameError: name 'variables' is not defined

defaultdict använder defaultdict kan till exempel ha odefinierade variabler inställda på noll:

>>> from collections import defaultdict
>>> variables = defaultdict(int, {'a': 42})
>>> eval('a * c', globals=variables)  # note that 'c' is not explicitly defined
0

Utvärdering av en sträng som innehåller en Python-bokstav med ast.literal_eval

Om du har en sträng som innehåller Python-bokstäver, till exempel strängar, flottörer osv, kan du använda ast.literal_eval att utvärdera dess värde istället för eval . Detta har den tillagda funktionen att endast tillåta vissa syntax.

>>> import ast
>>> code = """(1, 2, {'foo': 'bar'})"""
>>> object = ast.literal_eval(code)
>>> object
(1, 2, {'foo': 'bar'})
>>> type(object)
<class 'tuple'>

Detta är dock inte säkert för exekvering av kod som tillhandahålls av otillförlitlig användare, och det är trivialt att krascha en tolk med noggrant utformad inmatning

>>> import ast
>>> ast.literal_eval('()' * 1000000)
[5]    21358 segmentation fault (core dumped)  python3

Här är ingången en sträng av () upprepad en miljon gånger, vilket orsakar en krasch i CPython-parser. CPython-utvecklare anser inte buggar i parser som säkerhetsproblem.

Utför kod som tillhandahålls av en betrodd användare som använder exec, eval eller ast.literal_eval

Det är inte möjligt att använda eval eller exec att säkert köra kod från otillförlitlig användare. Till och med ast.literal_eval är benägen att kraschar i tolkaren. Det är ibland möjligt att skydda mot exekvering av skadlig kod, men det utesluter inte möjligheten till direkt kraschar i parser eller tokenizer.

För att utvärdera kod av en opålitlig användare måste du gå till någon modul från tredje part, eller kanske skriva din egen parser och din egen virtuella maskin i Python.



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow