web-dev-qa-db-fra.com

Utilisation de eval en Python?

Il y a une fonction eval() en Python sur laquelle je suis tombé en jouant. Je ne peux pas penser à un cas où cette fonction est nécessaire, sauf peut-être en tant que sucre syntaxique. Quelqu'un peut-il donner un exemple?

24
ooboo

evalet execsont un moyen pratique et rapide d’obtenir du code source de façon dynamique, peut-être de le modifier un peu, puis de l’exécuter, mais c’est rarement le meilleur moyen, en particulier dans le code de production, par opposition à "rapide". et "sale" prototypes & c.

Par exemple, si je devais traiter avec des sources Python aussi dynamiques, j'aurais recours au ast module - ast.literal_eval est BEAUCOUP plus sûr que eval(vous pouvez l'appeler directement sous la forme chaîne de l'expression, si une seule fois et repose uniquement sur des constantes simples, ou utilisez d'abord node = ast.parse(source), puis conservez le nodename__, éventuellement avec des visiteurs appropriés, par exemple pour une recherche de variable, puis literal_eval le nœud) - ou, une fois que le nœud a été correctement mis en forme et l'a vérifié pour des problèmes de sécurité, je pouvais compile(lui donnant un objet code) et créer un nouvel objet fonction à partir de celui-ci. Beaucoup moins simple (sauf que ast.literal_eval est aussi simple que evaldans les cas les plus simples!), Mais plus sûr et préférable pour un code de qualité production.

Dans de nombreuses tâches, j'ai déjà vu des personnes (ab-) utiliser execet evalpour, les puissantes fonctions intégrées de Python, telles que getattret setattrname__, en indexant dans globals(), etc., fournissent des solutions préférables et souvent plus simples. Pour des utilisations spécifiques telles que l'analyse JSON, les modules de bibliothèque tels que jsonsont meilleurs (voir le commentaire de SilentGhost sur la réponse de l'acouphène à cette question). Etc...

42
Alex Martelli

L’article Wikipedia sur eval est assez informatif et détaille diverses utilisations.

Certaines des utilisations suggérées sont:

  • Évaluation d'expressions mathématiques
  • Amorçage du compilateur
  • Scripting (les langages dynamiques en général sont très appropriés pour cela)
  • Tuteurs de langue
15
Noldorin

Vous pouvez l’utiliser pour permettre aux utilisateurs de saisir leurs propres "scriptlets": small expressions (ou même de petites fonctions), permettant de personnaliser le comportement d’un complex système .
Dans ce contexte, et si vous n’avez pas à vous soucier de la sécurité (par exemple, vous avez une base d’utilisateurs bien informée), alors eval () peut être un bon choix.

13
rob

Dans le passé, j’utilisais eval () pour ajouter une interface de débogage à mon application. J'ai créé un service telnet qui vous a plongé dans l'environnement de l'application en cours d'exécution. Les entrées ont été exécutées via eval () afin que vous puissiez exécuter de manière interactive des commandes Python dans l'application.

5
Andre Miller

Dans un programme que j'ai écrit une fois, vous disposiez d'un fichier d'entrée dans lequel vous pouviez spécifier des paramètres géométriques à la fois comme valeurs et comme expressions python des valeurs précédentes, par exemple:

a=10.0
b=5.0
c=math.log10(a/b)

Un analyseur python a lu ce fichier d'entrée et a obtenu les données finales évaluant les valeurs et les expressions à l'aide de eval ().

Je ne prétends pas que ce soit une bonne programmation, mais je n'ai pas eu à conduire de réacteur nucléaire.

4
Stefano Borini

Je l'utilise comme un analyseur JSON rapide ...

r='''
{
    "glossary": {
        "title": "example glossary"
        }
}
'''

print eval(r)['glossary']['title']
2
tinnitus

eval() n'est normalement pas très utile. L'une des rares choses pour lesquelles je l'utilisais (eh bien, c'était exec() en fait, mais c'est assez similaire) permettait à l'utilisateur de scripter une application que j'avais écrite en Python. S'il était écrit en C++, je devrais intégrer un interpréteur Python dans l'application.

1
Zifre

Eval est un moyen d'interagir avec l'interpréteur Python à partir d'un programme. Vous pouvez passer des littéraux à eval et les évalue comme des expressions Python.

Par exemple - 

print eval("__import__('os').getcwd()")

renverrait le répertoire de travail actuel.

à votre santé

1
Arnkrishn

Vous pouvez utiliser eval dans un décorateur:

#this replaces the original printNumber with a lambda-function,
#which takes no arguments and which calls the old function with
#the number 10
@eval("lambda fun: lambda: fun(10)")
def printNumber(i: int) -> None:
    print("The number is %i", i)

#call
printNumber()

alors que vous ne pouvez pas utiliser d'expressions complexes comme

@lambda fun: lambda: fun(10)
def ...

ni

@(lambda fun: lambda: fun(10))
def ...

Vous ne pouvez pas utiliser d'expression lambda ici, car le décorateur doit être soit un identifiant:

@myModule.functionWithOneArg

ou un appel de fonction:

@functionReturningFunctionWithOneArg(any, "args")

Vous voyez que l'appel de la fonction eval avec une chaîne a une syntaxe valide ici, mais pas l'expression lambda. (-> https://docs.python.org/3/reference/compound_stmts.html#function-definitions )

1
cmdLP

eval () est pour une phrase, tandis qu'exec () est pour plusieurs phrases.

nous les utilisons généralement pour ajouter ou visiter des scripts, comme bash Shell.

en raison de leur capacité à exécuter des scripts d’octets dans la mémoire, si vous avez des données ou un script importants, vous pouvez les décoder et les décompresser, puis faire tout ce que vous voulez.

0
BBDXF

Je l'ai utilisé pour entrer des valeurs variables dans le programme principal:

test.py var1 = 2 var2 = True

...

var1=0
var2=False
for arg in sys.argv[1:]:
    exec(arg)

Une manière grossière d'autoriser les arguments de mots clés dans le programme principal. S'il y a un meilleur moyen, faites le moi savoir!

0
buggy

Je viens de découvrir un bon usage de eval. J'étais en train d'écrire une suite de tests pour du code et de créer une classe de tests dans laquelle chaque méthode était un test à exécuter. Je voulais un moyen de pouvoir exécuter toutes les méthodes de test sans avoir à appeler chaque méthode individuellement. J'ai donc écrit quelque chose d'assez sale.

class Test:
    def __init__(self, *args):
       #bs

    def test1(self):
       #bs

    def test2(self):
       #bs

if __== "__main__":
    import argparse
    #argparse bs
    test = Test(*bs_args)
    for func in (i for i in dir(test) if i[0] != '_' and i not in test.__dict__):
        print(eval('test.{func}()'.format(func = func)))

L'évaluation dynamique des cas de test arbitraires est plutôt cool. Je dois juste écrire la méthode et, après avoir enregistré, je peux l'inclure dans ma suite de tests. En ce qui concerne le code, je vérifie simplement les méthodes définies dans l’objet test et s’assure qu’il ne s’agit pas de méthodes ou d’attributs «magiques» python par défaut pour cet objet. Après cela, je peux supposer que ce sont des méthodes et peuvent être évaluées.

0
Casey Craig