2016-10-13 1 views
0

파이썬 프로그램 내에서 실행될 문자열이 있고 x [1], x [2]와 같은 문자열의 일부 변수를 다른 것으로 변경하려고합니다. 이전에 2 개의 인수를 가진 eval을 사용 했었습니다. 두 번째 인수는 replaced_word : new_word와 함께 사용하는 명령입니다.하지만 이전에는 이처럼 이전에 가져온 모듈을 사용할 수 없습니다. 그래서 내가 이렇게하면Python2에서 가져온 모듈을 잃지 않고 사전에 eval 사용

from math import log 
eval(log(x[1], {x[1]: 1}) 

로그가 인식되지 않습니다. 전역 변수를 잃지 않고 어떻게 이와 같은 eval을 사용할 수 있습니까? 나는 문서를 이해할 수 없다 : https://docs.python.org/2/library/functions.html#eval 그래서 설명도 유용 할 것이다.

답변

1

의 거점으로 globals()으로 전역 dict 빌드 : 또는

from math import log 

# Copy the globals() dict so changes don't affect real globals 
eval_globals = globals().copy() 
# Tweak the copy to add desired new global 
eval_globals[x[1]] = 1 

# eval using the updated copy 
eval('log(x[1])', eval_globals) 

, 당신은 globals()이 수정되지 않은 사용 three-arg eval를 사용할 수 있지만, 또한 공급에서 먼저 확인 (수정) 될 localdict 이론적으로, 후자의 접근법은 표현식이 원래의 전역을 변형시킬 수있게하므로 addin g .copy()eval('log(x[1])', globals().copy(), {x[1]: 1})으로 설정하면 실수로 인한 위험을 최소화 할 수 있습니다. 그러나 병리학/악성 코드가이를 해결할 수 있습니다. eval은 결국 위험합니다. 샌드 박스로 만들 어서 상관없이 임의의 입력에 대해서는 신뢰하지 마십시오.

+0

전역을 복사하지 않는 것이 매우 효율적인 것처럼 보입니다. 게다가 나는이 평가를 수천 번 실행해야 매번 복사 할 때마다 너무 많은 오버 헤드가 발생하지 않을까? –

+0

@ JoaquimFerrer : Heh, 대체 방법을 추가하기 위해 답변을 업데이트하고 있었는데, 그 중 하나는 샌드 박스 만들기를 줄이거 나'globals()''dict'를 복사해야 할 필요성을 우회합니다. – ShadowRanger

+0

입력은 항상 나에 의해 만들어 지므로 걱정하지 않아도됩니다. 그것은 완벽하게 감사합니다! –

관련 문제