我应该总是在`except`语句中指定一个exceptiontypes吗?

当使用PyCharm IDE时,使用except:没有exceptiontypes触发从IDE的提醒这个exception子句是Too broad

我应该忽略这个build议吗? 或者是Pythonic总是指定exceptiontypes?

指定明确的exceptiontypes几乎总是更好。 如果使用裸体except:子句,则最终可能会捕获除期望捕获的exception之外的exception – 这可能会隐藏错误,或者在程序执行不到期望的时候更难debugging程序。

例如,如果要将一行插入到数据库中,则可能需要捕获指示行已经存在的exception,以便可以执行更新。

 try: insert(connection, data) except: update(connection, data) 

如果你指定一个空的except: ,你还会捕获一个套接字错误,指出数据库服务器已经崩溃了。 最好只捕捉你知道如何处理的exception – 程序在exception点失败通常比继续,但以奇怪的意外方式行事更好。

一种情况,你可能想要使用一个裸露的, except:是一个程序的顶层,你需要一直运行,就像一个networking服务器。 但是,那么你需要非常小心地loggingexception,否则就不可能找出问题所在。 基本上,一个程序中最多只能有一个这样的地方。

所有这一切的必然结果是,你的代码不应该raise Exception('some message')因为它强制客户端代码使用except: except Exception: 几乎一样坏)。 您应该定义一个特定于您想要表示的问题的exception(可能inheritance自一些内置的exception子类,如ValueErrorTypeError )。 或者你应该提出一个特定的内置的例外。 这使您的代码的用户在捕捉他们想要处理的exception时要小心。

你不应该忽视口译员给你的build议。

从Python的PEP-8风格指南:

在捕获exception时,尽可能提及特定的exception,而不是使用除了:子句之外的纯粹的exception。

例如,使用:

  try: import platform_specific_module except ImportError: platform_specific_module = None 

一个空的除了:子句将捕获SystemExit和KeyboardInterruptexception,使得用Control-C中断程序变得困难,并且可以掩盖其他问题。 如果要捕获所有发出程序错误的exception,请使用except Exception(除了等价于除BaseException之外的其他exception)。

一个很好的经验法则是限制使用裸“除外”从句到两种情况:

如果exception处理程序将打印出或logging回溯; 至less用户会意识到发生了错误。 如果代码需要做一些清理工作,然后让exception向上传播。 试试…终于可以是一个更好的方式来处理这种情况。

这不是Python的specfic。

例外的一个要点就是尽可能地把问题处理得尽可能地靠近。

所以你保持在特殊情况下的代码会触发问题和解决scheme“下一个”彼此。

问题是你无法知道所有可能由一段代码抛出的exception。 所有你可以知道的是,如果这是一个文件没有发现exception说,那么你可以陷阱,并提示用户得到一个做或取消function。

如果你把试图抓住这一点,那么不pipe你的文件例程中有什么问题(只读,权限,UAC,不是真正的pdf等),每一个都会放到你的文件中找不到catch,而你的用户尖叫“但它在那里,这个代码是废话”

现在有几种情况可以抓住一切,但是应该有意识地select。

它们被捕获,取消了一些本地的动作(比如创build或者locking一个资源,(例如在磁盘上打开一个文件来写),然后再抛出exception,在更高的层次上处理)

另一个你是你不在乎为什么它出错了。 例如打印。 你可能有一个全面的捕捉,说你的打印机有一些问题,请整理出来,而不是因为它杀死应用程序。 如果你的代码使用某种时间表执行一系列单独的任务,那么你会不希望整个事情死掉,因为其中一个任务失败了。

注意如果你这样做,我不能推荐某种exception日志logging,例如try catch日志结束,足够高。

你也将捕获如Control-C,所以不要这样做,除非你再次“抛出”它。 但是,在这种情况下,你应该使用“终于”。

总是指定exceptiontypes,有许多types你不想捕捉,如SyntaxErrorKeyboardInterruptMemoryError

这里是我使用的地方,除了没有types

  1. 快速和肮脏的原型

这是我的代码中未经检查的exception的主要用途

  1. 顶级main()函数,其中我logging每个未捕获的exception

我总是添加这个,以便生产代码不会溢出堆栈

  1. 在应用层之间

我有两种方法来做到这一点:

  • 第一种方法:当一个较高层次的层次调用一个较低层次的函数时,它将这些调用包装在types的excepts中,以处理“顶层”较低层次的exception。 但是我添加了一个通用的except语句,以检测低级别函数中未处理的较低级别exception。

我更喜欢这种方式,我发现更容易检测哪些exception应该被适当地捕获:当较高级别logging较低级别的exception时,我“更好地看到”问题

  • 第二种方式:底层图层的每个顶层函数都将其代码封装在一个通用对象中,除此之外,它捕获该特定图层上的所有未处理的exception。

有些同事更喜欢这种方式,因为它在“属于”的较低级别的function中保留较低级别的例外。

尝试这个:

 try: #code except ValueError: pass 

我从这个链接得到了答案,如果有其他人遇到这个问题检查出来