Python Eval: что не так с этим кодом? - PullRequest
2 голосов
/ 22 сентября 2009

Я пытаюсь написать очень простую утилиту Python для личного использования, которая подсчитывает количество строк в текстовом файле, для которого предикат, указанный в командной строке, имеет значение true. Вот код:

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

Когда я запускаю его, используя python count.py myFile.txt "int(line) == 0", я получаю следующую ошибку:

  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

Для меня это выглядит как совершенно правильный код Python (хотя я никогда не использовал eval Python раньше, поэтому я не знаю, каковы его причуды, если таковые имеются). Пожалуйста, скажите мне, как я могу это исправить, чтобы заставить его работать.

Ответы [ 5 ]

11 голосов
/ 22 сентября 2009

Попробуйте использовать exec вместо eval. Разница между 2 объясняется здесь

5 голосов
/ 22 сентября 2009

попробовать:

for line in handle:
  result += 1 if eval(pred) else 0
3 голосов
/ 22 сентября 2009
#!/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))

Использование: pywc.py predicate [FILE]...
Выведите количество строк, которые удовлетворяют predicate для заданных FILE (s).
Если нет FILE или если FILE равен -, прочитайте стандартный ввод.

2 голосов
/ 22 сентября 2009

Функция python eval () оценивает выражения, а не выражения. Попробуйте заменить строку eval () на:

result += eval(pred + " else 0")
0 голосов
/ 22 сентября 2009

Действительно, вы ищете функцию компиляции:

>> a = compile("toAdd = 1 if int('0') == 0 else 0", 'tmp2.py', 'exec')
>>> eval(a)
>>> toAdd
1

eval предназначен только для выражений ... скомпилировать, а скомпилировать последовательность операторов в кодовый блок, который затем можно будет вычислить.

...