Viele gute Antworten hier, aber keine beschreiben die Verwendung eval()im Kontext seiner globalsund localskwargs, dh eval(expression, globals=None, locals=None)(siehe Dokumente für eval hier ).
Diese können verwendet werden, um die Funktionen einzuschränken, die über die evalFunktion verfügbar sind . Wenn Sie beispielsweise einen neuen Python-Interpreter laden, ist der locals()und globals()derselbe und sieht ungefähr so aus:
>>>globals()
{'__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__doc__': None,
'__spec__': None, '__builtins__': <module 'builtins' (built-in)>,
'__package__': None, '__name__': '__main__'}
Es gibt sicherlich Funktionen innerhalb des builtinsModuls, die einem System erheblichen Schaden zufügen können. Aber es ist möglich, alles zu blockieren, was wir nicht zur Verfügung haben wollen. Nehmen wir ein Beispiel. Angenommen, wir möchten eine Liste erstellen, die eine Domäne der verfügbaren Kerne auf einem System darstellt. Für mich habe ich 8 Kerne, also würde ich eine Liste wollen [1, 8].
>>>from os import cpu_count
>>>eval('[1, cpu_count()]')
[1, 8]
Ebenso ist alles __builtins__verfügbar.
>>>eval('abs(-1)')
1
OK. Dort sehen wir also eine Funktion, die wir verfügbar machen möchten, und ein Beispiel für eine (von vielen, die viel komplexer sein können) Methode, die wir nicht verfügbar machen möchten. Also lasst uns alles blockieren.
>>>eval('[1, cpu_count()]', {'__builtins__':None}, {})
TypeError: 'NoneType' object is not subscriptable
Wir haben alle __builtins__Funktionen effektiv blockiert und damit ein gewisses Maß an Schutz in unser System gebracht. An diesem Punkt können wir beginnen, Funktionen wieder hinzuzufügen, die verfügbar gemacht werden sollen.
>>>from os import cpu_count
>>>exposed_methods = {'cpu_count': cpu_count}
>>>eval('cpu_count()', {'__builtins__':None}, exposed_methods)
8
>>>eval('abs(cpu_count())', {'__builtins__':None}, exposed_methods)
TypeError: 'NoneType' object is not subscriptable
Jetzt haben wir die cpu_countFunktion zur Verfügung, während wir immer noch alles blockieren, was wir nicht wollen. Meiner Meinung nach ist dies sehr mächtig und eindeutig aus dem Umfang der anderen Antworten, keine gemeinsame Implementierung. Es gibt zahlreiche Verwendungsmöglichkeiten für so etwas und solange es richtig gehandhabt wird, evalkann es meiner Meinung nach sicher zu einem guten Preis verwendet werden.
NB
Etwas anderes Cooles an diesen kwargsist, dass Sie anfangen können, Kurzschrift für Ihren Code zu verwenden. Angenommen, Sie verwenden eval als Teil einer Pipeline, um importierten Text auszuführen. Der Text muss keinen genauen Code enthalten, kann einem bestimmten Vorlagendateiformat folgen und dennoch alles ausführen, was Sie möchten. Zum Beispiel:
>>>from os import cpu_count
>>>eval('[1,cores]', {'__builtins__': None}, {'cores': cpu_count()})
[1, 8]