Beaucoup de bonnes réponses ici, mais aucune ne décrit l'utilisation de eval()dans le contexte de its globalset localskwargs, c'est-à-dire eval(expression, globals=None, locals=None)(voir la documentation eval ici ).
Ceux-ci peuvent être utilisés pour limiter les fonctions disponibles via la evalfonction. Par exemple, si vous chargez un nouvel interpréteur python, le locals()et globals()sera le même et ressemblera à ceci:
>>>globals()
{'__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__doc__': None,
'__spec__': None, '__builtins__': <module 'builtins' (built-in)>,
'__package__': None, '__name__': '__main__'}
Il existe certainement des fonctions au sein du builtinsmodule qui peuvent endommager considérablement un système. Mais il est possible de bloquer tout et tout ce dont nous ne voulons pas qu'il soit disponible. Prenons un exemple. Disons que nous voulons construire une liste pour représenter un domaine des cœurs disponibles sur un système. Pour moi, j'ai 8 cœurs, je voudrais donc une liste [1, 8].
>>>from os import cpu_count
>>>eval('[1, cpu_count()]')
[1, 8]
De même, tout __builtins__est disponible.
>>>eval('abs(-1)')
1
D'accord. Nous voyons donc là une fonction que nous voulons exposer et un exemple d'une méthode (parmi tant d'autres qui peuvent être beaucoup plus complexes) que nous ne voulons pas exposer. Alors bloquons tout.
>>>eval('[1, cpu_count()]', {'__builtins__':None}, {})
TypeError: 'NoneType' object is not subscriptable
Nous avons effectivement bloqué toutes les __builtins__fonctions et, à ce titre, apporté un niveau de protection à notre système. À ce stade, nous pouvons commencer à ajouter des fonctions que nous voulons exposer.
>>>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
Maintenant, nous avons la cpu_countfonction disponible tout en bloquant tout ce que nous ne voulons pas. À mon avis, c'est super puissant et clairement de la portée des autres réponses, pas une mise en œuvre commune. Il y a de nombreuses utilisations pour quelque chose comme ça et tant qu'il est manipulé correctement, je pense personnellement qu'il evalpeut être utilisé en toute sécurité à grande valeur.
NB
Une autre chose intéressante à ce sujet kwargsest que vous pouvez commencer à utiliser des raccourcis pour votre code. Supposons que vous utilisez eval dans le cadre d'un pipeline pour exécuter du texte importé. Le texte n'a pas besoin d'avoir un code exact, il peut suivre un format de fichier modèle et toujours exécuter tout ce que vous souhaitez. Par exemple:
>>>from os import cpu_count
>>>eval('[1,cores]', {'__builtins__': None}, {'cores': cpu_count()})
[1, 8]