Suche…


Syntax

  • eval (Ausdruck [, Globals = Keine [, Einheimische = Keine]]
  • exec (Objekt)
  • exec (Objekt, Globals)
  • exec (Objekt, Globals, Einheimische)

Parameter

Streit Einzelheiten
expression Der Ausdruck Code als String oder ein code - Objekt
object Die Anweisung Code als String oder ein code - Objekt
globals Das für globale Variablen zu verwendende Wörterbuch. Wenn für Einheimische keine Angabe gemacht wird, wird dies auch für Einheimische verwendet. Wenn nicht angegeben, werden die globals() des aufrufenden Bereichs verwendet.
locals Ein Mapping- Objekt, das für lokale Variablen verwendet wird. Wenn nicht angegeben, wird stattdessen die für globals verwendet. Wenn beide weggelassen werden, werden die globals() und locals() des aufrufenden Bereichs für globals bzw. locals verwendet.

Bemerkungen

In exec , wenn globals ist locals (dh sie auf das gleiche Objekt verweisen), wird der Code ausgeführt , als ob es auf der Modulebene ist. Wenn globals und locals unterschiedliche Objekte sind, wird der Code so ausgeführt, als wäre er in einem Klassenkörper .

Wenn das globals Objekt übergeben wird, der globals __builtins__ Schlüssel jedoch nicht angegeben ist, werden die __builtins__ Funktionen und Namen von Python automatisch zum globalen Bereich hinzugefügt. Um die Verfügbarkeit von Funktionen wie print oder isinstance im ausgeführten Bereich zu unterdrücken, lassen Sie globals den Schlüssel __builtins__ auf den Wert None . Dies ist jedoch keine Sicherheitsfunktion.

Die Python 2-spezifische Syntax sollte nicht verwendet werden. Die Python 3-Syntax funktioniert in Python 2. Daher sind die folgenden Formulare veraltet: <s>

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

Aussagen mit exec auswerten

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

Auswerten eines Ausdrucks mit eval

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

Einen Ausdruck vorkompilieren, um ihn mehrmals auszuwerten

compile eingebaute Funktion compile kann verwendet werden, um einen Ausdruck in ein Codeobjekt vorzukompilieren. Dieses Codeobjekt kann dann an eval übergeben werden. Dies beschleunigt die wiederholte Ausführung des ausgewerteten Codes. Der dritte zu compile Parameter muss die Zeichenfolge '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

Auswerten eines Ausdrucks mit eval mit benutzerdefinierten Globals

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

Als Plus kann sich der Code hier nicht versehentlich auf die außerhalb definierten Namen beziehen:

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

Bei Verwendung von defaultdict können zum Beispiel undefinierte Variablen auf Null gesetzt werden:

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

Auswertung eines Strings, der ein Python-Literal enthält, mit ast.literal_eval

Wenn Sie über eine Zeichenfolge verfügen, die Python-Literale enthält, z. B. Zeichenfolgen, Floats usw., können Sie ast.literal_eval , um den Wert anstelle von eval auszuwerten. Dies hat die zusätzliche Eigenschaft, nur bestimmte Syntax zuzulassen.

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

Dies ist jedoch nicht sicher für die Ausführung von Code, der von nicht vertrauenswürdigen Benutzern bereitgestellt wird, und es ist trivial, einen Interpreter mit sorgfältig ausgearbeiteten Eingaben zum Absturz zu bringen

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

Hier ist die Eingabe eine Zeichenfolge von () eine Million Mal wiederholt wird, was zu einem Absturz des CPython-Parsers führt. CPython-Entwickler betrachten Fehler im Parser nicht als Sicherheitsprobleme.

Ausführen von Code, der von nicht vertrauenswürdigem Benutzer mit exec, eval oder ast.literal_eval bereitgestellt wird

Es ist nicht möglich, eval oder exec zu verwenden, um Code von nicht vertrauenswürdigen Benutzern sicher auszuführen. Selbst ast.literal_eval neigt im Parser zum Absturz. Es kann manchmal vor böswilliger Code-Ausführung geschützt werden, schließt aber nicht aus, dass der Parser oder der Tokenizer vollständig abstürzt.

Um Code von einem nicht vertrauenswürdigen Benutzer auszuwerten, müssen Sie sich an ein Drittanbieter-Modul wenden oder vielleicht Ihren eigenen Parser und Ihre eigene virtuelle Maschine in Python schreiben.



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow