프로그래밍/Python

[Python] 파이썬 eval 과 exec 함수에 대하여

Joo-Topia 2019. 10. 4.
728x90
SMALL

오늘은 편리하면서 위험한 함수인 eval과 exec함수에 대해서 정리해보려고 한다.

두 함수 모두 파이썬 내장 함수이며, 아마 파이썬 언어를 공부하면서 지나가다 한 번쯤 봤을 수도 있다.

 

왜 편리하면서 위험한지 공부해보자.

 

eval 함수


eval 함수는 실행 가능한 문자열을 매개변수로 입력받아 문자열 자체를 실행한 결과값을 리턴해준다.

설명을 잘 못하니 직접 실행시켜보자.

>>>> print(eval("5+5"))
10

파이썬 해석기에서 바로 실행한 결과이다. 문자열 "5+5"를 연산 5+5로 해석한 뒤 결과값으로 정수 10을 반환하는 것을 볼 수 있다.

얼핏 보면 정말 편리한 기능을 가진 함수지만, 남용하면 시스템에 큰 오류를 일으킬 수도 있다.

아래 코드를 실행시켜보자.

string2 = '''
a+10
'''
def  what_is_eval():
    print('----------------------------------')
    print('this is code in what_is_eval')
    print('do "eval(string2)" in function : ',eval(string2))


if '__main__':
    a=20
    print('Local variables \'a\' is defined in \'__main__\'')
    print("Do \'print(a)\' : ",a)
    print('Let\'s run the \'what_is_eval\' function')
    what_is_eval()

빨간색 화살표를 기준으로 다른 지역 안으로 들어간다고 생각하면 된다.

main함수의 지역변수로 선언된 awhat_is_eval 함수에서 사용된다!
이상하다는걸 눈치 못 챘다면 지역변수와 전역 변수의 개념을 한번 정독하고 오면 이해될 것이다.

위 결과에서 알 수 있듯이 eval함수는 강제로 문자열 내부의 코드를 실행시키게 된다.
위 코드에서 what_is_eval함수를 호출하면 현재 스택에 있는 지역변수 a를 강제로 호출하게 된다. (물론 main 함수에서 a를 선언하지 않았다면 오류가 발생할 것이다.)
원래 what_is_eval 함수 안에서 다른 지역의 변수 a를 호출하면 오류가 발생해야 정상이다.


정리하자면 eval함수를 잘못 사용하면 원했던 변수가 아닌 다른 변수에 접근할 수도 있게 된다는 뜻이다.
별거 아닌 것 같지만 코드가 길어지고 변수가 많아지면 에러가 발생하는 상황을 피할 수 없을 것이다.

편리한 만큼 리스크가 큰 함수이니 주의해서 사용하도록 해야겠다.

 

 

exec 함수


string1 = '''
if a != 0:
    print("'a' is ",a)
else:
    print("'a' is zero.")
'''

def what_is_exec():
    print('----------------------------------')
    print('this is code in what_is_exec')

    print('do "exec(string1)" in function : ')
    exec(string1)

if '__main__':
    a=20
    print('Local variables \'a\' is defined in \'__main__\'')
    print("Do \'print(a)\' : ",a)
    print('Let\'s run the \'what_is_exec\' function')
    what_is_exec()

빨간색 화살표를 기준으로 다른 지역 안으로 들어간다고 생각하면 된다.

위에서 설명한 eval함수와 정말 비슷한 함수이다. 다른 점은 문장 자체를 입력받는다는 것이다.
조금 더 자세히 설명하자면 "5+5"같이 연산이 아니라 "a = 5+5"같은 수식이 들어가게 된다.
또한 eval은 연산의 결과를 반환했다면 exec는 말 그대로 수식을 실행하는 역할을 한다.

exec함수 또한 편리한 만큼 리스크가 큰 함수이니 주의해서 사용하도록 해야겠다.

마무리


실제 프로그래밍을 하면서 잘 사용하지 않는 함수들이긴 하지만, 정말 필요할 때 바로 사용할 수 있게 정리해 두는 것도 나쁘지 않은 것 같다.

728x90
SMALL

댓글