문제

나는이 사건을 가로 질러 달렸다 UnboundLocalError 최근에 이상한 것 같습니다.

import pprint

def main():
    if 'pprint' in globals(): print 'pprint is in globals()'
    pprint.pprint('Spam')
    from pprint import pprint
    pprint('Eggs')

if __name__ == '__main__': main()

생산 :

pprint is in globals()
Traceback (most recent call last):
  File "weird.py", line 9, in <module>
    if __name__ == '__main__': main()
  File "weird.py", line 5, in main
    pprint.pprint('Spam')
UnboundLocalError: local variable 'pprint' referenced before assignment

pprint 분명히 묶여 있습니다 globals, 그리고 묶일 것입니다 locals 다음 진술에서. 누군가가 어떻게 해결되지 않는지에 대한 설명을 제공 할 수 있습니까? pprint 바인딩에 globals 여기?

편집하다: 좋은 답변 덕분에 관련 용어로 내 질문을 명확히 할 수 있습니다.

컴파일 시간에 식별자 pprint 프레임에 로컬로 표시됩니다. 실행 모델에는 차이가 없습니다 어디 프레임 내에서 로컬 식별자가 바인딩되어 있습니까? "이 바이트 코드 명령어까지 글로벌 바인딩을 참조하십시오.이 시점에서 로컬 바인딩에 반등했습니다."또는 실행 모델이이를 설명하지 않습니까?

도움이 되었습니까?

해결책

파이썬이 보는 것 같습니다 from pprint import pprint 선과 자국 pprint 로컬 이름으로 main() ~ 전에 모든 코드 실행. Python은 Pprint가 로컬 변수가되어야한다고 생각하기 때문에 pprint.pprint() "할당"하기 전에 from..import 진술, 그것은 그 오류를 던진다.

그것은 내가 할 수있는만큼 의미가 있습니다.

물론 도덕은 항상 import 범위의 상단에있는 진술.

다른 팁

놀람은 어디에 있습니까? 어느 변수 글로벌이 해당 범위 내에서 재 할당하는 범위에서 컴파일러에 의해 해당 범위로 로컬로 표시됩니다.

수입이 다르게 처리되면 저것 놀라운 IMHO 일 것입니다.

그러나 그 기호를 사용한 후 모듈을 명명하지 않은 경우 또는 그 반대도 마찬가지입니다.

글쎄, 그것은 내가 조금 실험 할 정도로 흥미로 웠고 나는 http://docs.python.org/reference/executionmodel.html

그런 다음 여기 저기 코드를 땜질했습니다. 이것이 제가 찾을 수있는 것입니다.

암호:

import pprint

def two():
    from pprint import pprint
    print globals()['pprint']
    pprint('Eggs')
    print globals()['pprint']

def main():
    if 'pprint' in globals():
        print 'pprint is in globals()'
    global  pprint
    print globals()['pprint']
    pprint.pprint('Spam')
    from pprint import pprint
    print globals()['pprint']
    pprint('Eggs')

def three():
    print globals()['pprint']
    pprint.pprint('Spam')

if __name__ == '__main__':
    two()
    print('\n')
    three()
    print('\n')
    main()

산출:

<module 'pprint' from '/usr/lib/python2.5/pprint.pyc'>
'Eggs'
<module 'pprint' from '/usr/lib/python2.5/pprint.pyc'>

<module 'pprint' from '/usr/lib/python2.5/pprint.pyc'>
'Spam'

pprint is in globals()
<module 'pprint' from '/usr/lib/python2.5/pprint.pyc'>
'Spam'
<function pprint at 0xb7d596f4>
'Eggs'

방법에서 two() from pprint import pprint 그러나 이름을 무시하지 않습니다 pprint 안에 globals, 이후 global 키워드입니다 ~ 아니다 범위에서 사용됩니다 two().

방법에서 three() 선언이 없기 때문에 pprint 로컬 범위의 이름은 기본적으로 글로벌 이름으로 표시됩니다. pprint 이것은 모듈입니다

반면 main(), 처음에는 키워드입니다 global 사용 그래서 모든 참조 pprint 방법의 범위에서 main() will refer to the global 이름 pprint. 우리가 볼 수 있듯이 처음에는 모듈이며 global namespace 우리가하는 방법으로 from pprint import pprint

이것은 그 질문에 대답하지는 않지만 그럼에도 불구하고 내가 생각하는 흥미로운 사실.

=====================

편집하다 또 다른 흥미로운 것.

모듈이있는 경우 :

mod1

from datetime import    datetime

def foo():
    print "bar"

그리고 또 다른 방법은 다음과 같습니다.

mod2

import  datetime
from mod1 import *

if __name__ == '__main__':
    print datetime.datetime.now()

모듈을 가져온 이후 첫눈에 맞는 것 같습니다. datetime 안에 mod2.

이제 mod2를 스크립트로 실행하려고하면 오류가 발생합니다.

Traceback (most recent call last):
  File "mod2.py", line 5, in <module>
    print datetime.datetime.now()
AttributeError: type object 'datetime.datetime' has no attribute 'datetime'

두 번째 가져 오기 때문입니다 from mod2 import * 이름을 재정의했습니다 datetime 네임 스페이스에서는 첫 번째입니다 import datetime 더 이상 유효하지 않습니다.

도덕 : 따라서 수입 순서, 수입의 특성 (X 가져 오기 *) 및 수입 모듈 내에서 수입에 대한 인식 - 문제.

이 질문은 몇 주 전에 답변되었지만 답을 조금 명확히 할 수 있다고 생각합니다. 먼저 몇 가지 사실.

1 : 파이썬에서

import foo

거의 정확히 동일합니다

foo = __import__("foo", globals(), locals(), [], -1)

2 : 함수에서 코드를 실행할 때 Python이 함수에서 아직 정의되지 않은 변수가 발생하면 전역 범위가 보입니다.

3 : Python은 "현지인"이라는 기능에 사용하는 최적화를 가지고 있습니다. Python이 함수를 토큰 화하면 할당 한 모든 변수를 추적합니다. 이 변수는 각 변수에 로컬 단조로 증가하는 정수에서 숫자를 할당합니다. Python이 함수를 실행하면 로컬 변수만큼 많은 슬롯이있는 배열을 생성하고 각 슬롯을 "아직 할당되지 않은"것을 의미하는 특수 값을 할당하며 해당 변수의 값이 저장됩니다. 아직 할당되지 않은 로컬을 참조하면 Python은 그 특별한 가치를보고 UnboundLocalValue 예외를 던졌습니다.

이제 무대가 설정되었습니다. "PPRINT 가져 오기 PPRINT"는 실제로 할당의 형태입니다. 따라서 Python은 글로벌 변수를 막는 "pprint"라는 로컬 변수를 만듭니다. 그런 다음 함수에서 "pprint.pprint"를 참조하면 특수 값을 누르고 Python은 예외를 던졌습니다. 이 기능에 해당 가져 오기 명령문이없는 경우 Python은 일반적인 Look-in-Locals-ther-then-then-in-globals 해상도를 사용하고 Globals에서 Pprint 모듈을 찾을 수 있습니다.

이를 명확하게하기 위해 "글로벌"키워드를 사용할 수 있습니다. 물론 지금까지 당신은 이미 당신의 문제를 지나서 일했으며, 당신이 실제로 "글로벌"이 필요했는지 또는 다른 접근법이 요구되었는지 모르겠습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top