Beaucoup de bonnes réponses ici, mais aucune ne décrit l'utilisation de eval()
dans le contexte de son globals
et locals
kwargs, c'est-à-dire eval(expression, globals=None, locals=None)
(voir les documents relatifs à eval
ici ).
Ceux-ci peuvent être utilisés pour limiter les fonctions qui sont disponibles par le biais de l'interface utilisateur. eval
fonction. Par exemple, si vous chargez un nouvel interpréteur python, la fonction locals()
et globals()
seront les mêmes et ressembleront à quelque chose comme ça :
>>>globals()
{'__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__doc__': None,
'__spec__': None, '__builtins__': <module 'builtins' (built-in)>,
'__package__': None, '__name__': '__main__'}
Il y a certainement des fonctions au sein de la builtins
module qui peut causer des dommages importants à un système. Mais il est possible de bloquer tout ce que l'on ne veut pas rendre disponible. Prenons un exemple. Disons que nous voulons construire une liste pour représenter un domaine des cœurs disponibles sur un système. Dans mon cas, je dispose de 8 cœurs et je voudrais donc une liste [1, 8]
.
>>>from os import cpu_count
>>>eval('[1, cpu_count()]')
[1, 8]
De même, tous les __builtins__
est disponible.
>>>eval('abs(-1)')
1
Ok. Nous voyons donc une fonction que nous voulons exposer et un exemple d'une méthode (parmi de nombreuses 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__
et en tant que tel, il a apporté un niveau de protection dans notre système. À ce stade, nous pouvons commencer à réintégrer les 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 le cpu_count
fonction disponible tout en bloquant tout ce que nous ne voulons pas. À mon avis, ceci 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 que c'est traité correctement, je pense personnellement que eval
peut être utilisé en toute sécurité et à bon escient.
N.B.
Une autre chose qui est cool à propos de ces kwargs
c'est que vous pouvez commencer à utiliser des raccourcis pour votre code. Disons que vous utilisez eval dans le cadre d'un pipeline pour exécuter un texte importé. Le texte n'a pas besoin d'avoir un code exact, il peut suivre un certain format de fichier modèle, et toujours exécuter ce que vous voulez. Par exemple :
>>>from os import cpu_count
>>>eval('[1,cores]', {'__builtins__': None}, {'cores': cpu_count()})
[1, 8]
4 votes
La fonction Eval essaie d'exécuter et d'interpréter la chaîne de caractères (argument) qui lui est passée comme un code python. x=1 print (eval('x+1')) La sortie du code ci-dessus sera 2. L'inconvénient d'une telle approche est que l'utilisateur est libre d'écrire du code, ce qui peut entraîner des conditions difficiles, bien que vous puissiez restreindre l'accès des utilisateurs à de nombreuses variables et méthodes en passant des paramètres globaux et locaux dans la fonction eval.