2011-12-10 3 views
2

나는 일하고있는 작은 프로그램을위한 수업을 쓰려고했는데, 나는 들여 쓰기가 이상하게 실패했다. 필자가 쓴 내용에 진정으로 잘못된 것이 있는지 또는 파서의 잘못인지 궁금하다. 이것은 Fedora 15의 python 3.2 패키지에서 실패합니다. 당신이 그것을 실행할 수 있도록 요청으로파이썬 들여 쓰기 실패?

def __getitem__(self, key): 
    if CharacterStats.usesSubStats: 
     if key in self.subStats: 
     return self.subStats[key] 
    elif key in self.stats: #change this to 'if' and it works 
     return self.stats[key] 
    else: 
     raise KeyError(key) 
    #otherwise we end up right here. 

: 및 경우에만 CharacterStats.usesSubStats이 사실이고 key in self.subStats이 false 인 경우 http://pastebin.com/d8yQUm3U

+3

을 참고하시기 바랍니다 [파이썬 스타일 가이드] (http://www.python.org/dev/peps/pep -0008 /)는 4-space 들여 쓰기를 사용할 것을 제안합니다. – ThiefMaster

+3

정확히 말한대로하고 있습니다. 확실히 파서의 잘못이 아닙니다. –

답변

3

, 당신은 usesSubStats이 True이고 키가 subStats에없는 경우 KeyError를 던져 원하거나 usesSubStats이 거짓이며, 경우 키를 통계에 있지 않습니다. 그래서 나는 그 문제가/elif/else chaining이 당신처럼 생각하지 않는다면 이라고 생각합니다.

고려 :

def f(x): 
    if x == 1: 
     return 'first' 
    elif x == 2: 
     return 'second' 
    else: 
     return 'other' 

내가 예상 무엇을 수행하고 당신이 명심해야하는 패턴 희망

>>> f(1), f(2), f(3), f(4) 
('first', 'second', 'other', 'other') 

을 생산

. 테스트 코드 useSubStats에이 사실이기 때문에, 첫 번째 지점은 지금까지 테스트 :

def h(): 
    if condition(1, True): 
     if condition('1b', False): 
      return 'first branch' 
    elif condition(2, False): 
     return 'second branch' 
    else: 
     return 'other branch' 
    return 'fallthrough' 

>>> h() 
testing condition 1 
testing condition 1b 
'fallthrough' 

나는 당신이해야한다고 생각하는 방법을 정확히 모르겠어요 :

def condition(lab, val): 
    print('testing condition', lab); 
    return val 

def g(): 
    if condition(1, True): 
     return 'first branch' 
    elif condition(2, False): 
     return 'second branch' 
    else: 
     return 'other branch' 
    return 'fallthrough' 


>>> g() 
testing condition 1 
'first branch' 

그래서 코드는 다음과 같이 행동한다 "self_status in self.subStats"테스트가 실패한 후 실행이 if/elif/else 분기의 다음 구성원으로 다시 이동하여 테스트해야한다고 생각하는 것처럼 보입니다. 그것은 단순히 작동 방식이 아닙니다.

가 원하는 동작을 얻을 수있는 몇 가지 간단한 방법은 다음과 같습니다 False로 평가합니다 때문에 다음 분기 테스트 할 것 하나가 대신

if CharacterStats.usesSubStats and key in self.subStats: 

있어 있도록 평평하게하는 것입니다, 또는 - 너 자신을 발견 했으니, elif를 if로 만들어라. 다시 조건을 독립적으로 테스트하거나, 이전 답과 같이 재 작성한다.

의미가 있습니까?if/elif/else리스트는 일련의 가능성을 설명하며, 순차적으로 테스트 된 조건은 이며 첫 번째 true 조건 (마지막 else를 'elif 1 :'으로 사용)에 해당하는 분기 만이 실행됩니다. 일어나는 일에 따라 다음 분기로 이동하지 마십시오 분기 내에 있습니다.

+1

그래, 나는 첫 번째 가지에 들어가면 거기서'if'가 실패했을 때 엘프에게로 돌아갈 것이라고 생각했다. 모두 뛰어 내리지 마라. 한밤중에 숙취의 비트와 함께 코딩의 슬픈 결과. – Till

2

당신은 줄에 끝낼 수는 otherwise we end up right here을 표시했다.

elifif으로 변경하면 코드가 otherwise we end up right here 행에 도달 할 수 없습니다.

두 버전 중 어느 버전이 올바른지 말하기는 어렵습니다. 내가 제대로 당신의 의도를 짐작 제공, 아마도 다음은 그들 모두에게 명확한 대안이 될 것입니다 :

def __getitem__(self, key): 
    if CharacterStats.usesSubStats: 
     if key in self.subStats: 
      return self.subStats[key] 
    elif key in self.stats: 
     return self.stats[key] 
    raise KeyError(key) 
+0

원래의 질문에서와 같이, 아무것도 반환되는 (또는 던져지는) 유일한 시간은 키가 self.subStats에있는 경우입니다. 그렇지 않으면 아무 것도 반환되지 않습니다. else 문을 꺼내면 self.subStats에없는 키에 대해 KeyError를 제공합니다. 내가 제대로 작동하도록 만든 유일한 방법은 elif를 if로 대체하는 것입니다. – Till

+0

@ 힐 : 우리가 실행할 수있는 작은 완성 된 예제로 코드를 줄이고 예상과 달리 동작하는 입력을 제공 할 수 있습니까? – NPE

+0

완료하고 주 질문에 링크를 추가했습니다. – Till

0

나는 후자는 최종 else과 내부 된대로 raise으로 #otherwise..을 들여해야한다고 생각 "외부 블록"에 도달하지 못할 것입니다. 따라서 합리적인 IMO, IndentationError. 내가 제대로 이해하면

+0

당신이 거기에서 무슨 일이 일어나고 있는지 오해 한 것 같아요. – Till

0

self.statsself.subStats은 사전이므로 key이 포함되지 않은 경우 모두 KeyError을 발생시킵니다. 그래서

이유는 바로 쓸 수 없습니다 : 아마도

def __getitem__(self, key): 
    if CharacterStats.usesSubStats: 
     return self.subStats[key] 
    return self.stats[key] 

또는를 :

def __getitem__(self, key): 
    try: 
     if CharacterStats.usesSubStats: 
      return self.subStats[key] 
     return self.stats[key] 
    except KeyError: 
     raise CharacterStatsError(key) 
+0

'CharacterStats.usesSubStats'가 true 인 한, 스 니펫은 키가 항상'self.subStats'에 있다고 가정하기 때문에 이것은 작동하지 않습니다. 그러나 이것은 사실이 아닙니다. 하지만 나는 내 수업을 얼마나 어리석게 만들었는지 알기 시작했다. – Till

관련 문제