2012-07-25 3 views
0

아래 코드는 문제를 완전히 설명한다고 생각합니다. Test2 함수에서 x가 정의되지 않은 이유는 무엇입니까? Test3 함수가 오류를 반환하지 않는 이유는 무엇입니까? 기능 Test2에서파이썬의 exec 함수의 이상한 동작

>>> def Test1(): 
exec('x=2') 
print(str(x)) 


>>> Test1() 
2 
>>> def Test2(): 
global x 
exec('x=2') 
print(str(x)) 


>>> Test2() 

Traceback (most recent call last): 
File "<pyshell#39>", line 1, in <module> 
Test2() 
File "<pyshell#38>", line 4, in Test2 
print(str(x)) 
NameError: global name 'x' is not defined 

>>> def Test3(): 
global x 
x=2 
print(str(x)) 

>>> Test3() 
2 
+2

무엇을하려하십니까? 'global'을 사용하지 말고'exec'를 사용하지 마십시오; 그들은 잘못 설계된 코드로 이어지고,'exec'의 경우 안전하지 않은 코드로 이어집니다. –

+0

txt 파일에서 사전 기반의 데이터베이스를로드하려고했습니다. –

+0

그래, 그러지 마. 대신 데이터베이스를 JSON으로 저장하고'mydata = json.load (open ('mydb.txt'))'와 같이로드하시오. –

답변

2

@Colin Dunklau에 의해 주석이 그대로 @SanSS에 의해 주어진 대답은, 정확,하지만 난을 추가하고 싶었 조금 더 많은 정보. 한 가지 당신이 여행 수도 있습니다 global x않습니다 execed 코드를 수행합니다. 따라서 exec는 변수 x을 만들고, print x은 전역 변수를 읽으려고합니다. 이 두 가지 예가 도움이 될 수 있습니다. . . 여기에 하나의 DICT를 전달하여

, 당신이 사용하는 간부에게 그 간부가 전역에 할당 있도록 전역 지역 주민 등 다음 간부 인 에드 코드의 글로벌 선언을 포함하여 여기에

>>> def Test2(): 
...  global x 
...  exec 'x=2' in globals() 
...  print(str(x)) 
>>> Test2() 
2 

, 그러나, 일반적으로 exec를 사용하는 것이 좋습니다 아니라,

>>> def Test2(): 
...  global x 
...  exec('global x; x=2') 
...  print(str(x)) 
>>> Test2() 
2 

가 반복하기 : 당신은 간부가 인쇄 문이 다음 읽는 글로벌에 할당합니다. 파이썬이 어떻게 작동 하는지를 이해하기 위해 가끔씩 이런 것들을 가지고 놀아도 좋지만, 이것이 코드로 실제로 뭔가를 수행하는 좋은 방법 인 경우는 거의 없습니다.

3

, 파이썬 글로벌 네임 스페이스에서 검색합니다 있도록, x 전역 변수임을 주장하는 global x을 선언합니다. 글로벌 네임 스페이스에 정의 된 x 변수가 없기 때문에 NameError이 발생합니다.

당신이 Test2exec 값 2 x라는 새로운 지역 변수를 생성하지만, 글로벌되지 않도록 당신의 eval 기능은 global 문에 의해 영향을받지 않는 것을 볼 수 있습니다 the official documentation을 읽는다면, printglobal 문에 의해 영향을받으며 존재하지 않는 전역 이름 공간에서 x을 검색합니다. 테스트 3에서 x=2 문은 따라서 값 x를라는 이름의 전역 변수를 만드는 global 문에 의해 영향을 받는다 2.

+0

왜 Test3 함수가 작동합니까? exec ('x = 2 ')는 x = 2 –

+1

@ user1354439와 같아야합니다. 설명을 보려면 제 대답을 참조하십시오. 글로벌 명령문은 execed 코드로 전달되지 않으므로'exec ('x = 2 ')'는 동일하지 않습니다 – BrenBarn

+0

@BrenBarn 당신이 대답했을 때 그것을 설명하기 위해 내 의견을 편집하고 있었지만, 당신만큼 간단하게 설명 할 수는 없었습니다 : P –