Beaucoup de bonnes réponses ici, mais aucune ne décrit l'utilisation de eval()
dans le contexte de its globals
et locals
kwargs, 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 eval
fonction. 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 builtins
module 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_count
fonction 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 eval
peut être utilisé en toute sécurité à grande valeur.
NB
Une autre chose intéressante à ce sujet kwargs
est 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]