Zoeken…


Syntaxis

  • eval (expression [, globals = None [, locals = None]])
  • exec (object)
  • exec (object, globals)
  • exec (object, globals, locals)

parameters

Argument Details
expression De expressiecode als een tekenreeks of een code object
object De instructiecode als een tekenreeks of een code object
globals Het woordenboek dat moet worden gebruikt voor globale variabelen. Als de lokale bevolking niet is opgegeven, wordt dit ook gebruikt voor de lokale bevolking. Indien weggelaten, worden de globals() van globals() gebruikt.
locals Een toewijzingsobject dat wordt gebruikt voor lokale variabelen. Als dit wordt weggelaten, wordt in plaats daarvan degene gebruikt die voor globals is doorgegeven. Als beide worden weggelaten, worden de globals() en locals() van het globals gebruikt voor respectievelijk globals en locals .

Opmerkingen

In exec , als globals locals (dat wil zeggen dat ze naar hetzelfde object verwijzen), wordt de code uitgevoerd alsof deze zich op moduleniveau bevindt. Als globals en locals verschillende objecten zijn, wordt de code uitgevoerd alsof deze in een hoofdgedeelte van de klasse staat .

Als het globals object wordt doorgegeven, maar geen __builtins__ sleutel opgeeft, worden de ingebouwde functies en namen van Python automatisch toegevoegd aan het globale bereik. Om de beschikbaarheid van functies zoals onderdrukken print of isinstance in de uitgevoerde scope, laat globals de sleutel __builtins__ toegewezen aan waarde None . Dit is echter geen beveiligingsfunctie.

De Python 2-specifieke syntaxis mag niet worden gebruikt; de syntaxis van Python 3 werkt in Python 2. De volgende formulieren zijn dus verouderd: <s>

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

Uitspraken evalueren met exec

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

Een uitdrukking evalueren met eval

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

Een uitdrukking vooraf compileren om deze meerdere keren te evalueren

compile ingebouwde functie kan worden gebruikt om een uitdrukking vooraf te compile naar een code-object; dit code-object kan vervolgens worden doorgegeven aan eval. Dit versnelt het herhaald uitvoeren van de geëvalueerde code. De derde te compile parameter moet de string '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

Een expressie evalueren met eval met behulp van aangepaste globals

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

Als een plus, hiermee kan de code niet per ongeluk verwijzen naar de buiten gedefinieerde namen:

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

Het gebruik van defaultdict maakt het bijvoorbeeld mogelijk om ongedefinieerde variabelen op nul te zetten:

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

Evaluatie van een string met een Python letterlijk met ast.literal_eval

Als je een string hebt die Python-literalen bevat, zoals strings, floats enz., ast.literal_eval je ast.literal_eval gebruiken om de waarde ast.literal_eval te evalueren in plaats van eval . Dit heeft de toegevoegde functie dat alleen bepaalde syntaxis wordt toegestaan.

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

Dit is echter niet veilig voor de uitvoering van code die wordt aangeboden door niet-vertrouwde gebruikers, en het is triviaal om een tolk met zorgvuldig vervaardigde invoer te laten crashen

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

Hier is de invoer een reeks van () die een miljoen keer wordt herhaald, wat een crash in CPython parser veroorzaakt. CPython-ontwikkelaars beschouwen bugs in parser niet als beveiligingsproblemen.

Code uitgevoerd door niet-vertrouwde gebruiker met behulp van exec, eval of ast.literal_eval

Het is niet mogelijk om eval of exec te gebruiken om code van niet-vertrouwde gebruikers veilig uit te voeren. Zelfs ast.literal_eval is gevoelig voor crashes in de parser. Het is soms mogelijk om te waken tegen het uitvoeren van schadelijke code, maar het sluit de mogelijkheid van regelrechte crashes in de parser of de tokenizer niet uit.

Om code door een niet-vertrouwde gebruiker te evalueren, moet u zich wenden tot een module van derden, of misschien uw eigen parser en uw eigen virtuele machine in Python schrijven.



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow