Python try-else

geo*_*wa4 532 python exception-handling

声明的可选else条款的用途是try什么?

Bla*_*rad 801

else如果执行从底部开始try- 如果没有异常,则执行块中的语句.老实说,我从来没有找到需要.

但是,处理例外说明:

使用else子句比向try子句添加其他代码要好,因为它可以避免意外捕获由try ... except语句保护的代码未引发的异常.

所以,如果你有一个方法可以,例如,抛出一个IOError,你想捕获它引发的异常,但是如果第一个操作成功,你想做其他事情,而你不想从中捕获一个IOError那个操作,你可能写这样的东西:

try:
    operation_that_can_throw_ioerror()
except IOError:
    handle_the_exception_somehow()
else:
    # we don't want to catch the IOError if it's raised
    another_operation_that_can_throw_ioerror()
finally:
    something_we_always_need_to_do()
Run Code Online (Sandbox Code Playgroud)

如果你只是把它放在another_operation_that_can_throw_ioerror()后面operation_that_can_throw_ioerror,它except会捕获第二个调用的错误.如果你把它放在整个try块之后,它将永远运行,直到它之后finally.将else让您确保

  1. 如果没有例外,第二次操作只会运行,
  2. 它在finally块之前运行,并且
  3. IOError它所引发的任何东西都没有被抓住

  • 没有"try-scoped变量"这样的东西.在Python中,变量范围仅由模块,函数和理解建立,而不是由控制结构建立. (25认同)
  • 从这个答案中不清楚*"从底部掉下来"*意味着 - 这不仅是因为异常而发生的,而且还因为`return`,`continue`或`break`而发生. (8认同)
  • 还要记住,try-block中使用的变量可以在else-block中使用,所以如果你不希望在else-block中有更多异常,你应该总是考虑使用这个变量. (7认同)
  • else子句允许您编写仅在未抛出异常时才有意义的代码; except子句可以简单地通过.如果将逻辑放在try块中,则可能会无意中隐藏代码中的错误.永远不要压制你没想到的异常. (6认同)
  • 这没关系,因为在try之外可以看到try-scoped变量是否存在else. (3认同)

Izk*_*ata 97

使用有一个重要原因else- 风格和可读性.保留代码可能会导致代码处理异常,这通常是一个好主意.例如,比较这些:

try:
    from EasyDialogs import AskPassword
    # 20 other lines
    getpass = AskPassword
except ImportError:
    getpass = default_getpass
Run Code Online (Sandbox Code Playgroud)

try:
    from EasyDialogs import AskPassword
except ImportError:
    getpass = default_getpass
else:
    # 20 other lines
    getpass = AskPassword
Run Code Online (Sandbox Code Playgroud)

第二个是好的,当except不能提前返回,或重新抛出异常.如果可能的话,我会写:

try:
    from EasyDialogs import AskPassword
except ImportError:
    getpass = default_getpass
    return False  # or throw Exception('something more descriptive')

# 20 other lines
getpass = AskPassword
Run Code Online (Sandbox Code Playgroud)

注意:答案从最近发布的重复复制在这里,所以这一切的"AskPassword"的东西.


Dar*_*con 48

一个用途:测试一些应引发异常的代码.

try:
    this_should_raise_TypeError()
except TypeError:
    pass
except:
    assert False, "Raised the wrong exception type"
else:
    assert False, "Didn't raise any exception"
Run Code Online (Sandbox Code Playgroud)

(此代码应在实践中抽象为更通用的测试.)


Aar*_*all 41

Python try-else

elsetry语句的可选子句的用途是什么?

摘要

return声明是否有运行没有异常,如果不是被打断continue,breakelse声明.

其他答案错过了最后一部分.

来自文档:

else如果控制流出return子句的末尾,则执行可选子句.*

(Bolding补充道.)脚注上写着:

*目前,控制"流出端部"除了在异常或一个的执行的情况下continue,breakelse语句.

它确实需要至少一个前面的except子句(参见语法).所以它真的不是"尝试其他",它是"尝试 - 除了 - 否定( - 最终)",而try(和return)是可选的.

Python指南详细阐述了预期的用法:

try ... except语句有一个可选的else子句,当存在时,必须遵循所有except子句.如果try子句不引发异常,则必须执行的代码很有用.例如:

for arg in sys.argv[1:]:
    try:
        f = open(arg, 'r')
    except IOError:
        print 'cannot open', arg
    else:
        print arg, 'has', len(f.readlines()), 'lines'
        f.close()
Run Code Online (Sandbox Code Playgroud)

使用else子句比向try子句添加其他代码要好,因为它可以避免意外捕获由try ... except语句保护的代码未引发的异常.

示例区分continuebreak块后面的代码

如果您处理错误,该else块将不会运行.例如:

def handle_error():
    try:
        raise RuntimeError('oops!')
    except RuntimeError as error:
        print('handled a RuntimeError, no big deal.')
    else:
        print('if this prints, we had no error!') # won't print!
    print('And now we have left the try block!')  # will print!
Run Code Online (Sandbox Code Playgroud)

现在,

>>> handle_error()
handled a RuntimeError, no big deal.
And now we have left the try block!
Run Code Online (Sandbox Code Playgroud)

  • 文档的要点:“使用 `else` 子句比在 `try` 子句中添加额外的代码更好,因为它可以避免意外捕获由 `try .. 保护的代码未引发的异常。 .除了`声明。” (2认同)

Ali*_*ell 23

Try-except-else非常适合将EAFP模式duck-typing结合使用:

try:
  cs = x.cleanupSet
except AttributeError:
  pass
else:
  for v in cs:
    v.cleanup()
Run Code Online (Sandbox Code Playgroud)

您可能认为这个天真的代码很好:

try:
  for v in x.cleanupSet:
    v.clenaup()
except AttributeError:
  pass
Run Code Online (Sandbox Code Playgroud)

这是在代码中意外隐藏严重错误的好方法.我在那里进行了错误的清理,但是让我知道的AttributeError被吞没了.更糟糕的是,如果我写得正确怎么办,但是清理方法偶尔会传递一个具有错误名称属性的用户类型,导致它在中途无声地失败并保持文件未闭合?祝你好好调试一下.


Roa*_*ich 17

我发现即使有异常,当你需要进行清理时它仍然非常有用:

try:
    data = something_that_can_go_wrong()
except Exception as e: # yes, I know that's a bad way to do it...
    handle_exception(e)
else:
    do_stuff(data)
finally:
    clean_up()
Run Code Online (Sandbox Code Playgroud)


Unk*_*own 9

即使您现在无法想到它的使用,您也可以打赌必须使用它.这是一个缺乏想象力的样本:

else:

a = [1,2,3]
try:
    something = a[2]
except:
    print "out of bounds"
else:
    print something
Run Code Online (Sandbox Code Playgroud)

没有else:

try:
    something = a[2]
except:
    print "out of bounds"

if "something" in locals():
    print something
Run Code Online (Sandbox Code Playgroud)

something如果没有抛出错误,您可以在此处定义变量.您可以在try块外删除它,但如果定义了变量,则需要进行一些混乱的检测.

  • S. Lott:'print something'可以引发一个你不想拦截的异常. (12认同)
  • 什么是'某事= a [2]; 在try:block中打印一些东西? (3认同)
  • 打印时,'something'的值可能会在__str __()方法中引发错误.虽然在这个例子中该值实际上只是2,但你也可以指出这里也没有越界异常. (3认同)

Shi*_*waj 8

try:
    statements # statements that can raise exceptions
except:
    statements # statements that will be executed to handle exceptions
else:
    statements # statements that will be executed if there is no exception
Run Code Online (Sandbox Code Playgroud)

例子 :

try:
    age=int(input('Enter your age: '))
except:
    print ('You have entered an invalid value.')
else:
    if age <= 21:
        print('You are not allowed to enter, you are too young.')
    else:
        print('Welcome, you are old enough.')
Run Code Online (Sandbox Code Playgroud)

输出 :

>>> 
Enter your age: a
You have entered an invalid value.
>>> RESTART
>>> 
Enter your age: 25
Welcome, you are old enough.
>>> RESTART
>>> 
Enter your age: 13
You are not allowed to enter, you are too young.
>>> 
Run Code Online (Sandbox Code Playgroud)

复制自:https://geek-university.com/python/the-try- except-else-statements/


its*_*dok 7

try-elsePEP 380中有一个很好的例子.基本上,它归结为在算法的不同部分进行不同的异常处理.

它是这样的:

try:
    do_init_stuff()
except:
    handle_init_suff_execption()
else:
    try:
        do_middle_stuff()
    except:
        handle_middle_stuff_exception()
Run Code Online (Sandbox Code Playgroud)

这允许您编写更接近异常发生位置的异常处理代码.


fed*_*qui 7

来自错误和异常#处理异常 - docs.python.org

try ... except陈述有一个可选else条款,如果存在,必须遵循所有除条款之外的条款.如果try子句不引发异常,则必须执行的代码很有用.例如:

for arg in sys.argv[1:]:
    try:
        f = open(arg, 'r')
    except IOError:
        print 'cannot open', arg
    else:
        print arg, 'has', len(f.readlines()), 'lines'
        f.close()
Run Code Online (Sandbox Code Playgroud)

使用else子句比向try子句添加其他代码要好,因为它可以避免意外捕获由try ... except语句保护的代码未引发的异常.


ste*_*anB 5

查看Python参考,似乎else是在try没有异常的情况下执行的。当控制从try子句的末尾流出时,将执行可选的else子句。2 else子句中的异常不由前面的except子句处理。

深入研究python有一个例子,如果我理解正确,try他们会在块中尝试导入模块,当该模块失败时,您将获得异常并绑定默认值,但是当它起作用时,您可以选择进入else块并绑定所需的内容(请参阅示例和说明的链接)。

如果您尝试在代码catch块中进行工作,则可能会引发另一个异常-我想这就是代码else块派上用场的地方。

  • “ else子句中的异常不由前面的except子句处理。” 那是有用的部分。谢谢。 (4认同)