Viele gute Antworten hier, aber keine beschreiben die Verwendung eval()
im Kontext seiner globals
und locals
kwargs, 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 eval
Funktion 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 builtins
Moduls, 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_count
Funktion 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, eval
kann es meiner Meinung nach sicher zu einem guten Preis verwendet werden.
NB
Etwas anderes Cooles an diesen kwargs
ist, 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]