2014-01-20 2 views
1

저는 파이썬 범위 규칙을 이해하려고합니다. 나는 동일한 모듈 그것은 NameError 실패클래스의 private 모듈 변수에 액세스합니다.

bar = "bar" 
_bar = "underscore" 
__bar = "double underscore" 

def foo(): 
    print bar 
    print _bar 
    print globals()["__bar"] 
    print __bar 

class Foo: 
    def __init__(self): 
     print bar 
     print _bar 
     print globals()["__bar"] 
     print __bar #NameError: global name '_Foo__bar' is not defined 

foo() 
Foo() 

에서 클래스 액세스 "매우 개인"변수를하려고이 작업을 수행합니다. 나는 그것에 대해 아무것도 찾을 수 없습니다. 왜 실패하고 왜이 행동이 묘사 되었습니까?

+0

전체 출력을 게시 할 수 있습니까? 또는 완전한 예외 메시지? –

+0

그래, 삭제 된 이유는 - 놀랍게도 이것은 독립 실행 형 이름 인'__bar'에서도 발생하기 때문입니다. 당신이 문서에서 올린 인용문은 그 사실을 명백하게 진술하지 않습니다. –

+0

@DanielRoseman : * 클래스 정의에서 텍스트로 발생하는 식별자 * 및 *이 변환은 식별자가 사용 된 구문 적 컨텍스트와 독립적입니다. * 메서드 정의를 포함하여 클래스 본문의 모든 식별자가 포함됩니다 . 속성, 전역 또는 로컬인지 여부는 중요하지 않습니다. –

답변

3

클래스 정의 내에서 시작 이름은 이중 밑줄이있는입니다. 클래스 이름을 접두어로 포함하도록 다시 작성됩니다.

클래스 내에서 이름을 '비공개'로 표시하고 하위 클래스로 덮어 쓰지 않도록 보호하는 기능입니다. 텍스트로 클래스 정의에서 발생하는 식별자이 시작 이상의 문자를 밑줄 두 개 이상의 밑줄로 끝나지 않는 경우, 그것은 개인 이름 간주됩니다를 엉망으로

개인 이름 : identifiers documentation 참조 그 계급. 개인 이름은 코드가 생성되기 전에 더 긴 형식으로 변환됩니다. 변환은 앞에 밑줄이 제거되고 밑줄이 하나만 삽입 된 클래스 이름을 이름 앞에 삽입합니다. 예를 들어, Ham이라는 클래스에서 발생하는 __spam 식별자는 _Ham__spam으로 변환됩니다. 이 변환은 식별자가 사용 된 구문 적 컨텍스트와 독립적입니다. 변환 된 이름이 너무 긴 경우 (255 자보다 길 경우) 구현 정의 절단이 발생할 수 있습니다. 클래스 이름이 밑줄만으로 구성되어 있으면 변환이 수행되지 않습니다.

모듈 전역에 이중 밑줄 접두사를 사용하지 않는 것이 좋습니다. 이렇게해야 할 필요는 없으며 단일 밑줄로 값이 모듈 내부에 있음을 알리기에 충분합니다.

이러한 값이 붙어있는 경우에는 맹 글링되지 않은 별칭을 만들거나 globals()[name]을 사용하십시오.

+0

그렇다면 클래스 내부에서 이중 점수 상수에 액세스하는 가장 좋은 방법은 무엇입니까? 'globals() [ '__ bar']'는 약간 해킹 된 것처럼 보입니다. –

+1

@PauloBu : 또는,'sys.modules [__ name __] .__ bar'를 사용하십시오 ... 이중 밑줄 이름을 전역 변수로 사용하지 않는 것이 가장 좋습니다. –

+0

그래, 그게 내가 생각했던거야 :) –

관련 문제