2011-03-28 2 views
9

Python 3 소스 코드에서 범위 분석을 일부 수행하려고하고 있으며 클래스 정의 내에서 비 ​​로컬 명령문이 작동하는 방식에 문제가 있습니다.클래스 정의에있는 Python 비 지역 문

클래스 정의는 본문을 새 네임 스페이스 (dict이라고 부름) 내부에서 실행하고 클래스 이름을 유형 (name, bases, dict)의 결과에 바인딩합니다. 로컬이 아닌 x는 해당 로컬이 아닌 범위에서 어딘가에 바인딩되는 변수를 참조하는 한 작동해야합니다. 다음 코드는

def A(): 
    v = 1 
    class B: 
     nonlocal v 
     v = 2 

사람이 설명 할 수

완벽하게 실행되는 동안

class A: 
    v = 1 
    class B: 
     nonlocal v 
     v = 2 

을하지만이

SyntaxError: no binding for nonlocal 'v' found 

와 함께 실패

이에서 나는 컴파일하고 실행하려면 다음 코드를 기대 함수 정의의 종결과 클래스 정의의 차이점은 무엇입니까?

+0

더 많은 연구 - 마지막 코드 샘플에서 A의 locals()는 {v : 1}이고 B 내부는 {v : 1}입니다. 2, ''__module__'': ''__main__'', ''__locals__' : {...}} – Andyrooger

답변

10

렉시컬 범위 지정은 함수 네임 스페이스에만 적용됩니다. 그렇지 않으면 클래스 내부에 정의 된 메서드는 클래스 수준 특성을 "볼"수 있습니다 (의도적으로 메서드 내에서 self의 특성으로 액세스해야 함).

클래스 수준 변수가 메서드에서 참조로 건너 뛴 것과 같은 제한으로 인해 nonlocal 키워드가 계속 작동하지 않습니다.

+0

감사합니다. 나는 모든 레벨에서 똑같이 작동 할 수있는 아주 기본적인 형태의 스택이 있다고 가정했다. symtable 모듈에 주목하면 의사가 내 마음을 바꾸었지만 실제로 무슨 일이 일어나고 있는지 또는 왜 대답 할 때까지는 이해하지 못했습니다. – Andyrooger

4

파이썬은 클래스와 함수 정의를 다르게 처리합니다. 예를 들어, A.v은 A의 변수가 아니라 오히려 그것의 속성입니다. 따라서 클래스에 의해 생성 된 네임 스페이스는 범위가 아닙니다. 나는 그것을 사용하려고 시도 할 때 nonlocal이 작동하지 않는다는 사실에 놀라지 않습니다.

+0

답장을 보내 주셔서 감사합니다. 따라서 함수 범위는 정의 될 때가 아니라 실행될 때 만들어집니다. 클래스 정의의 본문은 다른 네임 스페이스에서 즉시 실행되는 것으로 가정하므로이 실행 기간 동안 범위를 만들지 않습니까? 내부 클래스가 외부 클래스의 특성에 액세스 할 수없는 동일한 이유로 인해 발생하는 경우 궁금하네요 ... – Andyrooger

+0

임시 범위를 만들지 만 범위가 다른 * kind *입니다. 컴파일러는 어떤 특성이 표시되는지 (내부 범위의 참조와 외부 범위의 쓰기 모두) 다른 결정 규칙을 사용합니다. – ncoghlan