在错误时正确退出While循环

2 投票
3 回答
6603 浏览
提问于 2025-04-17 00:12

我很好奇,用Python处理这个错误的“正确”方式是什么,特别是在使用while循环的时候。在这个例子中,我可以简单地先检查一下字符串里是否有[-1]这个字符,但实际上我遇到的问题的代码要复杂得多。

try:
    while mystring[-1] == '!' #Will throw an error if mystring is a blank string
         print("Exclamation!")
         mystring = mystring[:-1]
    return mystring
except:
    return ""

简单来说,我的问题是我的while循环依赖于一个检查,而这个检查在循环内部经过一些处理后,有时会抛出错误。上面的例子只是对这个问题的一个(可能过于)简单的说明。我用一系列的try: excepts来解决了这个问题,但我觉得这不是解决这个问题的“正确”方式。

3 个回答

2

可以用 mystring.rstrip('!') 来去掉字符串末尾的 '!' 字符哦;-)

如果问题比较复杂,正确的做法是处理操作可能抛出的 IndexError 错误。

try:
    while mystring[-1] == '!' #Will through an error if mystring is a blank string
         print("Exclamation!")
         mystring = mystring[:-1]
    return mystring
except IndexError:
    return ""

另一种方法是先检查字符串是否为空,避免使用会引发异常的操作:

while mystring and mystring[-1] == '!': # lazy boolean expression evaluation
      mystring = mystring[:-1]
return mystring

还有一种版本,不使用懒惰的布尔表达式评估:

if not mystring:
    return mystring
while mystring[-1] == '!':
    mystring = mystring[:-1]
    if not mystring:
        break
return mystring

我个人更喜欢第二种版本,特别是如果你把 mystring[-1] == '!' 改成 mystring.endswith('!') 的话(但在这种情况下你就不需要检查是否为空,因为 endswith 已经帮你做了这一步)。

3

对于你的例子,你可以简单地这样做:

while mystring and mystring[-1] == '!':
    print("Exclamation!")
    mystring = mystring[:-1]
return mystring

这样做是有效的,因为如果mystring是空的,它会提前结束循环,这样你就不会尝试访问空字符串的-1索引了。

编辑:正如Winston所指出的,你可以通过使用str.endswith来避免所有特殊情况,像下面的代码那样。

while mystring.endswith('!'):
    print("Exclamation!")
    mystring = mystring[:-1]
return mystring
3

你现在的代码有两个地方是不应该这样做的:

  1. 你捕获了所有的异常,其实你应该只捕获你关心的特定异常。
  2. 你把整个循环都放在了try块里,最好只把可能引发异常的那一句话或表达式放进去。

如果你发现自己在Python中经常使用while循环,那说明你可能没有充分利用Python的特性。其实,Python提供的工具让你几乎总是可以使用某种for循环。由于我没有看到你具体的代码,所以不能确定这是否真的适用。如果你想在这方面得到帮助,可以把代码发到 http://codereview.stackexchange.com

解决这个问题的一个通用方法是写一个处理异常的函数,然后使用它。

def last_character(string):
    try:
       return string[-1]
    except IndexError:
       return ' '

while last_character(mystring) == '!'
    mystring = mystring[:-1]
return mystring

实际上,在很多情况下,已经有不需要异常处理的标准写法。这个循环可以很容易地用.endswith()方法来写。通过使用这些方法或者自己创建的方法,你可以更干净地处理异常。

撰写回答