2010-11-24 5 views
2

다음 함수에서 try:을 일찍 끝내고 있습니까? def 블록 외부에 동일한 코드를 넣으면 제대로 작동합니다.무엇을 만들고 있습니까? 일찍 종료 하시겠습니까?

tiles = ['095D', '094M'] 
in_file = 'in_file' 
out_file = 'out_file' 
expression = ''' "FIELDNAME" LIKE 'STUFF' ''' 

def foobar(in_file, out_file, expression): 
    print in_file, out_file, expression 
    try: 
     print 'this is trying' 
     #pretty print tile list, from http://stackoverflow.com/questions/2399112/python-print-delimited-list 
     tiles = ','.join(map(str,tiles)) 
     print 'made it past tiles!' 
     print 'From %s \nselecting %s \ninto %s' % (in_file, tiles, out_file) 

    except: 
     print 'Made it to the except block!' 

foobar(in_file, out_file, expression) 

결과 : same code not in a def

D:\> python xx-debug.py 
in_file out_file "FIELDNAME" LIKE 'STUFF' 
this is trying 
Made it to the except block! 

결과 :

당신은 흥미로운 버그
this is trying 
made it past tiles! 
From in_file 
selecting 095D,094M 
into out_file 
+0

등이 있으며, 초보자도 그렇게 할 것입니다. –

+3

@aaronasterling "포켓몬 예외 처리 - 모두 잡아 야해!" –

+2

예외를 지정하지 않고'except :'하지 않아야합니다. 그러면 KeyboardInterrupt 같은 것을 잡을 것입니다. KeyboardInterrupt는 거의 당신이 원하는 것이 아닙니다. – ThiefMaster

답변

3

글로벌 범위에서 tiles을 정의했기 때문에 작동하지 않는 이유가 있습니다. 함수에서 당신은 tiles에 할당하고 있습니다. 그러면 tiles이 함수에서 로컬 범위 이름이됩니다. 이것은 함수의 코드가 전역 범위에서 전혀 tiles을 찾지 않는다는 것을 의미합니다. 할당에서

, 당신은 (그것을 로컬로 할당되기 전에이입니다.) tiles를 얻을 에 노력하고이 제기되고 예외가 발생, 당신은 할당되지 않은 지역 변수에 액세스하려고하기 때문이다.

빠른 수정 global을 사용하는 것입니다 : 다른 사람들이 말했듯이, 그냥 뭔가를하지 않고 예외를 포착하지 않는

... 
def foobar(in_file, out_file, expression): 
    global tiles 
    ... 

. 코드를 디버깅 할 때 예외가 발생하여 원인을 찾아서 수정할 수 있습니다. 예외가 발생합니다. 어느 try ... except을 제거하거나 except을 다음과 같이 예외를 가지고 그것에 대해 유용한 정보를 인쇄 :

try: 
    ... 
except Exception, e: 
    print 'Oh noes!', e 

이 읽을 많이있을 수 있습니다,하지만 당신은 파이썬을 많이 이해 더 나은 당신이 할 경우 읽기 : 파이썬 모듈의 범위와 기능 범위에 변수 정의를 처리하는 방법을

http://docs.python.org/reference/executionmodel.html

그것은 설명 등 또한 예외를 다룹니다.

+0

실제 제외 블록은 다음을 제외합니다 : \ n \ tprint gp.GetMessages() \ n' (http://webhelp.esri.com/arcgiSDEsktop/9.3/body.cfm?tocVisable=1&ID=924&TopicName = 오류 % 20handling % 20with % 20Python) 가능한 가장 단순한 오류를 재현 할 때이를 추출했습니다. 무슨 일이 일어나는지 나에게 알리는 것에 감사드립니다. –

-1

. 따라서 모듈 범위가 tiles이고 그 범위가 global이 아니므로 함수 내에 새로운 tiles 변수가 생성됩니다. 이건 괜찮아. 또는 문법의 lvalue (왼쪽의 tiles)가 로컬 인 것처럼 보이면 전체 문이 타일에 대한 참조가 로컬을 의미한다고 생각한다는 점을 제외하고는 괜찮을 것입니다. 따라서 맵 구조에서 모듈 tites을 사용하는 대신 로컬 하나가 아직 존재하지 않는 것을 제외하고는 로컬 맵을 사용합니다.

이것은 Python의 버그 일 수 있지만 의도 한 것일 수 있습니다.

+1

버그가 아니며, 사실 아주 잘 정의되어 있습니다. 전역 변수와 지역 변수에는 차이가 있습니다. 이것들은 당신이'global' 키워드를 가지고있는 것과 같은 경우입니다. :) – Blixt

+0

그렇지만 전역 범위를 먼저 사용하여 오른쪽 부분을 평가 한 다음 로컬 변수를 만들고 할당하는 것이 좋습니다. 파이썬은 그 이름의 로컬 변수가 생성되었는지 여부를 미리 검사합니다. – jpsimons

3

예외 출력 : 타일 실제로 글로벌 공간에 정의되어 있기 때문에

Traceback (most recent call last): 
    File "sof.py", line 19, in <module> 
    foobar(in_file, out_file, expression) 
    File "sof.py", line 11, in foobar 
    tiles = ','.join(map(str,tiles)) 
UnboundLocalError: local variable 'tiles' referenced before assignment 

자,이 문제가 발생합니다.따라서 함수는 다음과 같아야합니다.

def foobar(in_file, out_file, expression): 
    global tiles 
    ... 
+2

'tiles'는 함수에서 지역적으로 정의되어 있기 때문에 일어나고 있다고 설명해야합니다. 즉,'global' 키워드를 사용하지 않으면 전역 변수가 무시됩니다. 이 오류는 'tiles'를 전역 적으로 정의하지 않은 경우에도 발생합니다. – Blixt

+0

UnboundLocalError 메시지는 어떻게 얻었습니까? 나가 얻는 모두는 침묵이다. –

+0

'except'는 예외를 삼킨다. 'except'가 없으면 그 오류가 발생합니다. – Blixt

관련 문제