Вопрос

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

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, поэтому не знаю, в чем его особенности, если таковые имеются).Подскажите, пожалуйста, как это исправить, чтобы все заработало.

Это было полезно?

Решение

#!/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(с).
Без FILE, или, когда FILE равен -, читать стандартный ввод.

Другие советы

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

пытаться:

for line in handle:
  result += 1 if eval(pred) else 0

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

result += eval(pred + " else 0")

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top