python缩进失败?
我正试图为我一直在开发的一个小程序编写一个类,但我遇到了一个奇怪的缩进失败。我想知道我写的东西是否真的有问题,或者是解析器的错。这在Fedora15的Python3.2包中失败python缩进失败?,python,python-3.x,Python,Python 3.x,我正试图为我一直在开发的一个小程序编写一个类,但我遇到了一个奇怪的缩进失败。我想知道我写的东西是否真的有问题,或者是解析器的错。这在Fedora15的Python3.2包中失败 def __getitem__(self, key): if CharacterStats.usesSubStats: if key in self.subStats: return self.subStats[key] elif key in self.stats: #c
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.UseSubstats
为true且键入self.subStats
为false
当您将elif
更改为if
时,您消除了这种可能性:代码永远无法到达,否则我们就在这里结束了行
很难说这两个版本中哪一个是正确的。如果我猜对了你的意图,或许以下两种方法都更为清晰:
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)
我认为你应该将#缩进,否则..
与提升
,因为后者在最后的else
中,并且永远不会到达“外部块”。。因此,我认为这是一个合理的缩进错误。如果我理解正确,您希望在
usesSubStats为True,且键不在subStats中,或者如果usesSubStats为
False和key不在统计信息中。所以我认为问题在于
如果/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 key in self.subStats”测试失败后,执行应该返回到if/elif/else分支的下一个成员,并进行一级测试。不过,这根本不是它的工作原理
有几种简单的方法可以让你达到你想要的行为:一种是把它展平,让它变得更简单
if CharacterStats.usesSubStats and key in self.subStats:
相反,它将计算为False,因此下一个分支将被测试,或者——正如您自己发现的那样——将elif设为if,这再次导致独立测试该条件,或者像前面的答案一样重写
这有意义吗?if/elif/else列表描述了一系列可能性,并按顺序测试了条件,仅执行与第一个true条件对应的分支(将最后一个else作为“elif 1:”)。根据分支内发生的情况,您不会移动到下一个分支。因为self.stats
和self.subStats
都是字典,如果它们不包含键,它们都会引发键错误
那么,为什么不写:
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)
仅供参考,作者建议使用4个空格的缩进,这样可以使代码更具可读性。它完全按照您的要求执行。这当然不是解析器的错。在实现中,与原始问题一样,返回(或抛出)任何内容的唯一时间是如果键位于self.subStats中,否则将不返回任何内容。如果我去掉else语句,它将为任何不在self.subStats中的键提供一个KeyError。我发现,要使其正常工作,唯一的方法是用if替换elif。@Till:您能将代码简化为我们可以运行的完整小示例,并提供与预期相反的输入吗?这不是一个真正的最小示例。您能把它归结为您的getitem方法和几个测试结果的方法调用示例吗?尝试将其作为(失败的)单元测试来编写。我认为您误解了其中的内容。这不会起作用,因为您的代码片段会假定只要CharacterStats.usesubstats
为真,键就始终位于self.subStats
中。但事实并非如此。但是我开始意识到我的课堂布置是多么的愚蠢。是的,我出于某种原因认为如果它进入第一个分支,而其中的如果失败,它就会跳回elif;而不是完全跳出来。在午夜的时候编码的结果是一种宿醉的结果。