Python Eval: Quel est le problème avec ce code?
-
12-09-2019 - |
Question
Je suis en train d'écrire un utilitaire Python très simple pour un usage personnel qui compte le nombre de lignes dans un fichier texte pour lequel un prédicat spécifié dans la ligne de commande est vrai. Voici le code:
import sys
pred = sys.argv[2]
if sys.argv[1] == "stdin" :
handle = sys.stdin
else :
handle = open(sys.argv[1])
result = 0
for line in handle :
eval('result += 1 if ' + pred + ' else 0')
print result
Quand je lance à l'aide python count.py myFile.txt "int(line) == 0"
, je reçois l'erreur suivante:
File "c:/pycode/count.py", line 10, in <module>
eval('toAdd = 1 if ' + pred + ' else 0')
File "<string>", line 1
toAdd = 1 if int(line) == 0 else 0
Cela ressemble à du code Python parfaitement valide pour moi (même si je ne l'ai jamais utilisé le eval de Python avant, donc je ne sais pas ce que ses bizarreries, le cas échéant, sont). S'il vous plaît me dire comment je peux résoudre ce problème pour le faire fonctionner.
La solution
#!/usr/bin/env python
import fileinput, sys
pred = eval('lambda line: ' + sys.argv[1])
print sum(1 for line in fileinput.input(sys.argv[2:]) if pred(line))
Utilisation: pywc.py predicate [FILE]...
Numéro d'impression des lignes qui satisfont predicate
pour FILE
donné (s).
Sans FILE
, ou lorsque le fichier est -, lire l'entrée standard
Autres conseils
essayer:
for line in handle:
result += 1 if eval(pred) else 0
La fonction eval python () évalue les expressions, pas des déclarations. Essayez de remplacer la ligne eval () avec:
result += eval(pred + " else 0")
Vraiment, vous êtes à la recherche de la fonction de compilation:
>> a = compile("toAdd = 1 if int('0') == 0 else 0", 'tmp2.py', 'exec')
>>> eval(a)
>>> toAdd
1
eval est destiné uniquement à des expressions ... compiler en séquence la compilation des déclarations dans un bloc de code qui peut ensuite être eval'ed.