Wie beschrieben in der Dokumentation , eval()
hat auch globals
y locals
Schlüsselwortargumente, die verwendet werden können, um die Funktionen einzuschränken, die über den eval
Funktion. Wenn Sie zum Beispiel einen neuen Python-Interpreter laden, wird die locals()
y globals()
werden gleich sein und in etwa so aussehen:
>>> globals()
{'__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__doc__': None,
'__spec__': None, '__builtins__': <module 'builtins' (built-in)>,
'__package__': None, '__name__': '__main__'}
Es gibt sicherlich Funktionen innerhalb der builtins
Modul, das einem System erheblichen Schaden zufügen kann. Aber es ist möglich, alles zu blockieren, was wir nicht haben wollen. Nehmen wir an, wir wollen eine Liste erstellen, die eine Domäne der verfügbaren Kerne auf einem System darstellt. In meinem Fall 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 werden alle __builtins__
ist verfügbar.
>>> eval('abs(-1)')
1
Versuchen wir, den Zugriff auf alle Globals zu blockieren:
>>> eval('[1, cpu_count()]', {'__builtins__':None}, {})
TypeError: 'NoneType' object is not subscriptable
Wir haben praktisch alle __builtins__
Funktionen und brachte so ein gewisses Maß an Schutz in unser System. Jetzt können wir damit beginnen, die Funktionen, die wir offenlegen wollen, wieder hinzuzufügen.
>>>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 und blockiert dennoch alles, was wir nicht wollen. Meiner Meinung nach ist dies super mächtig und eindeutig aus dem Rahmen der anderen Antworten, nicht eine gemeinsame Umsetzung. Es gibt zahlreiche Verwendungsmöglichkeiten für so etwas, und solange es richtig gehandhabt wird, bin ich persönlich der Meinung eval
kann sicher und mit großem Nutzen eingesetzt werden.
N.B..
Noch etwas anderes ist cool an diesen kwargs
ist, dass Sie beginnen können, eine Kurzschrift für Ihren Code zu verwenden. Nehmen wir an, Sie verwenden eval als Teil einer Pipeline, um einen importierten Text auszuführen. Der Text muss keinen exakten Code haben, er kann einem Schablonen-Dateiformat folgen und trotzdem alles ausführen, was Sie möchten. Zum Beispiel:
>>> from os import cpu_count
>>> eval('[1,cores]', {'__builtins__': None}, {'cores': cpu_count()})
[1, 8]