2009-09-21 4 views
2

저는 개인적인 용도로 매우 간단한 Python 유틸리티를 작성하려고합니다.이 유틸리티는 명령 줄에 지정된 조건자가 참인 텍스트 파일의 줄 수를 계산합니다. 여기 코드는 다음과 같습니다Python Eval :이 코드에 어떤 문제가 있습니까?

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 

이 내가 전에 파이썬의 평가를 사용한 적이 있지만 (나에게 완벽하게 유효한 파이썬 코드 모양을 , 그래서 나는 그것의 단점이 있다면 무엇인지 모른다.) 이 문제를 해결할 수있는 방법을 알려주십시오.

답변

3
#!/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]...
인쇄 번호 부여 FILE (들)에 대한 predicate을 만족시킨다.
FILE이 없거나 FILE이 - 인 경우 표준 입력을 읽습니다.

+0

이것은 단순하고 효율성면에서 다른 버전에 비해 월등히 뛰어납니다. –

+1

감사합니다. 이것은 다른 버전보다 훨씬 빠르다. 왜냐하면 해석기가 O (N) 대신에 술어 O (1)을 구문 분석하고 컴파일하기 때문이다. – dsimcha

11

eval 대신 exec를 사용해보십시오. 2의 차이점을 설명합니다 here

+0

감사합니다. 간단한 질문, 간단한 대답. – dsimcha

+0

대단히 반갑습니다! – ennuikiller

2

python eval() 함수는 명령문이 아닌 표현식을 평가합니다. 로 평가() 라인을 교체하십시오 :

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

'eval ('int (line) == 0 else 0')'SyntaxError'를 생성합니다. – jfs

5

시도 :

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

정말, 당신은 컴파일 기능을 찾고 있습니다 :

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

평가 만 표현하기위한 것입니다 .. . 컴파일 된 문장의 순서를 평가할 수있는 코드 블럭으로 컴파일하십시오.