2014-04-01 2 views
6

최소파이썬 범위 지정 문제

class foo: 
    loadings = dict(hi=1) 
    if 'hi' in loadings: 
     print(loadings['hi']) 
     # works 
     print({e : loadings[e] for e in loadings}) 
     # NameError global name 'loadings' not defined 

내가뿐만 아니라 클래스 네임 스페이스를 참조하는 시도 예를하지만이 작동하지 않습니다 중 하나

class foo: 
    loadings = dict(hi=1) 
    if 'hi' in loadings: 
     print(loadings['hi']) 
     #works 
     print({e : foo.loadings[e] for e in foo.loadings}) 
     #NameError: name 'foo' is not defined 

그리고 물론

, 예상대로 작동합니다.

class foo: 
    loadings = dict(hi=1) 
    if 'hi' in loadings: 
     print(loadings['hi']) 

print({e : foo.loadings[e] for e in foo.loadings}) 

개미가 왜이 범위 문제가 발생 하는지를 이해하고, 내가 미쳐있는 일을하려고한다면 다른 방법으로 최선의 방법을 이해해야한다. 제 느낌은 첫 번째 코드 스 니프가 그대로 작동해야한다는 것입니다. 물론 그렇지 않습니다.

목표

내가 통조림 데이터베이스 쿼리와 함께 일부 CSV/JSON 파일에 대한 DataManager에 클래스/모듈을 만드는 오전, 내 프로그램 및 취득 데이터에 대한 원 스톱 상점. 정적 데이터와 일부 동적 데이터가 있으므로 같은 클래스에서 정적 및 비 정적 데이터 멤버를 많이 사용하는 것처럼 보입니다. 이것들이 모듈 수준의 변수가 될 수 있음을 알고 있지만 정적 클래스 데이터 멤버를 갖는 개념을 좋아합니다 (아마도 자바의 편견 때문에). 어떤 도움이 많이 나는 위의이

class foo: 
    loadings = dict(hi=1) 
    temp = dict() 
    for e in loadings: 
     temp[e] = loadings[e] # keep in mind this is a minimal example, I probably wouldn't do (just) this 
    print(temp) # works 
    del temp 

같은 될 것으로, 클래스 범위에 머물 목록 이해력를 펼쳤다 결국

(지금은)

내 솔루션을 감사합니다 그것은 아니지만, 꽤는 Name and Binding docs 당 지금

+0

내가 그 흥미주의하는 생각 –

+0

....'인쇄 ({K가 k, v in loadings.items()})'가 작동합니다.그래서'loadingings'은 적어도 독해력 내에서 볼 수 있습니다. – cmd

+0

이것은 한번로드 된 클래스의 정적 데이터이므로 init 함수에서는 수행되지 않았습니다. 나는'runonce' 또는 어떤 것과 같은 깃발을 가질 수 있었지만, 클래스 수준의 코드가 이유가 있다고 보입니다. – user25064

답변

4

작동 :

클래스 블록에 정의 된 이름 범위는 블록 블록으로 제한됩니다. 메소드의 코드 블록으로 확장되지 않습니다. 에는 기능 범위를 사용하여 구현 된 이기 때문에 이해 내역과 생성자 표현식이 포함됩니다. 이 다음은 이 실패한다는 것을 의미 :

class A: 
    a = 42 
    b = list(a + i for i in range(10)) 

은 자세한 내용은 this answer를 참조하십시오.

dict([(e,loadings[e]) for e in loadings]) 

그러나 Python3에서 실행하는 경우이 코드가 깨질 것 : 그들이 함수의 범위를 사용하지 않고 구현 된 이후 Python2에서


, 지능형리스트를 사용하는 것이 가능하다. 그래서 여기 Python2 및 Python3에서 일하는 것이 다른 해결 방법입니다 : V에 대한 : 당신이 초기화 함수 내에서 모든 것을해야

class Foo: 
    def loadings(): 
     load = dict(hi=1) 
     if 'hi' in load: 
      print(load['hi']) 
      print({e:load[e] for e in load}) 
     return load 
    loadings = loadings() 

print(Foo.loadings) 
+0

대단히 감사합니다. 명확하고 간결한 설명이 필요합니다. 나는 나의 의도가 마지막 코드 블록의 마지막 두 줄을'print (Foo.loadings)'와 같은 것으로 대체하고 그것을 정적 데이터 멤버로 사용하는 것이라고 지적하고 싶었다. – user25064