我正在尝试为一个我正在研究的小程序编写一个类,我遇到了一个奇怪的缩进失败。我想知道我写的内容是否真的有问题,或者是否是解析器的错。这在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.
根据要求,您可以运行它:http://pastebin.com/d8yQUm3U
答案 0 :(得分:3)
如果我理解正确,你想抛出KeyError if usesSubStats为True,key不在subStats中,或者如果usesSubStats为 假和关键不在统计数据中。所以我认为问题是这样的 如果/ elif / else链接不能像你想象的那样工作。
考虑:
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为True,所以只测试了第一个分支:
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'
所以你的代码表现得像这样:
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'
我不确定你认为它应该如何表现,但似乎你期望在“if.subStats中的if键”测试失败后,执行应该回到if / elif的下一个成员/ else分支一级并测试。但这根本不是它的工作方式。
有几种简单的方法可以获得您想要的行为:一种是将其展平以便它是
if CharacterStats.usesSubStats and key in self.subStats:
相反,它将评估为False,因此下一个分支将进行测试,或者 - 如果您发现自己 - 将elif设为if,这再次导致该条件被独立测试,或在之前的答案中重写。
这有意义吗? if / elif / else列表描述了一系列可能性,其中条件是按顺序测试的,并且只执行对应于第一个真实条件的分支(将最后的else作为'elif 1:')。根据在分支中发生的情况,您不会移动到下一个分支。
答案 1 :(得分:2)
当且仅当otherwise we end up right here
为真且CharacterStats.usesSubStats
为假时,您才可以在标有key in self.subStats
的行上结束。
当您将elif
更改为if
时,您可以消除这种可能性:代码永远无法到达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)
答案 2 :(得分:0)
我认为你应该用#otherwise..
缩进raise
,因为后者在最终的else
内,而且“外部块”永远不会到达。因此,合理的, IMO,IndentationError。
答案 3 :(得分:0)
由于self.stats
和self.subStats
是字典,如果它们不包含KeyError
,它们都会提出key
。
那么为什么不写:
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)