2012-08-09 3 views
4

이 동작에 대한 적절한 설명을 찾을 수 없습니다.Python - locals() 및 클로저

>>> def a(): 
...  foo = 0 
...  print locals() 
...  def b(): 
...   print locals() 
...  b() 

>>> a() 
{'foo': 0} 
{} 

그러나 :

>>> def a(): 
...  foo = 0 
...  print locals() 
...  def b(): 
      foo 
...   print locals() 
...  b() 

>>> a() 
{'foo': 0} 
{'foo': 0} 

내가 두 번째 경우에 폐쇄가 있다는 것을 이해하지만, 내가 실제로 어떤 조건이 기능 locals()를 반환해야하는지 아래에 자세한 설명을 찾을 수 없습니다.

+0

내가 너라면, Michael Schuller의 답변 (그의 의견에 대한 upvote/downvote 아래의 체크 표시)을 수락 할 것입니다. 사랑을 나누고 그의 노력에 감사를 표하십시오! – rsegal

+0

@rsegal Rostyslav Dzinko의 답변은 depeer입니다. –

+0

사실! 나는 그것을 더 잘 표현해야만했다 : 필자는 필자가 가장 좋아하는 것이 라기보다는 대답에 대해 당신의 호의를 베풀어 야한다고 더 많이 말하려고했다. 그러나 Michael의 대답이 더 직접적으로 귀하의 질문에 대한 답으로, 파이썬이 모호한 값에 대한 범위를 검색한다는 것을 느꼈습니다. 이는 모범적 인 행동이었습니다! – rsegal

답변

3

열차() 내장 함수는 객체 코드 에 결합하고, 통역자는 소스 코드에 이름을 수신 할 때까지 충전된다 로컬 심볼 테이블을 출력한다.

번째 예, 분해하면 B 함수 코드 LOAD_GLOBAL foo에 바이트 코드 명령을 포함 할 것이다. 이 LOAD_GLOBAL 명령은 범위를 위로 이동하고 바깥 쪽 foo 이름을 찾은 다음 클로저 (함수 b) 코드 객체의 co_names 속성에 이름 오프셋을 추가하여 코드 객체에 바인딩합니다.

locals() 함수는 로컬 심볼 테이블을 인쇄합니다 (이전에 말한 것처럼 함수의 코드 객체의 co_names 속성).

코드 객체에 대한 자세한 내용은 here을 참조하십시오.

5

당신이 폐쇄 내 foo에 할당하지 않으면 (이 어딘가에 foo를 찾거나 예외를 throw 할 때까지 최대), 파이썬이 범위를 한 단계 위로의 foo에 해결합니다. 두 번째 예에서는 b()foo을 언급함으로써

, 당신은 b() 내에서 지역 주민에 foo를 넣어하지만 a()의 신체 내에서 foo에 해결합니다. 당신이 할당하는 경우 foo = 1b()에, 당신은 출력으로

{'foo': 0} 
{'foo': 1} 

을 볼 것이다,라고.

+0

고마워,하지만 더 자세한 내부 정보가 필요해. ( –