Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 我是否应该始终在'except'语句中指定异常类型?_Python_Exception_Pep8 - Fatal编程技术网

Python 我是否应该始终在'except'语句中指定异常类型?

Python 我是否应该始终在'except'语句中指定异常类型?,python,exception,pep8,Python,Exception,Pep8,当使用PyCharm IDE时,如果在没有异常类型的情况下使用except:,IDE会提示此异常子句太宽了 我应该忽略这个建议吗?或者总是指定异常类型是Pythonic吗?你也会用它捕获例如Control-C,所以除非你再次“抛出”它,否则不要这样做。但是,在这种情况下,您应该使用“finally”。始终指定异常类型,有许多类型是您不想捕获的,例如语法错误,键盘中断,内存错误等。您不应该忽略解释器给您的建议 从Python的样式指南中: 捕获异常时,请随时提及特定的异常 可能,而不是使用裸exc

当使用PyCharm IDE时,如果在没有异常类型的情况下使用
except:
,IDE会提示此异常子句
太宽了


我应该忽略这个建议吗?或者总是指定异常类型是Pythonic吗?

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

始终指定异常类型,有许多类型是您不想捕获的,例如
语法错误
键盘中断
内存错误
等。

您不应该忽略解释器给您的建议

从Python的样式指南中:

捕获异常时,请随时提及特定的异常 可能,而不是使用裸except:子句

例如,使用:

一个简单的Exception:子句将捕获SystemExit和KeyboardInterrupt异常,从而使其更难执行 用Control-C中断程序,可以掩盖其他问题。 如果要捕获所有表示程序错误的异常,请使用 Exception:(bare except相当于except BaseException:)

一个很好的经验法则是将裸露的'except'子句的使用限制为两个 案例:

如果异常处理程序将打印或记录 回溯;至少用户会意识到发生了错误。 如果代码需要做一些清理工作,但随后允许异常 随着上升而向上传播。尝试…最终可以是一个更好的方法 处理这个案子


几乎总是最好指定一个显式异常类型。如果使用裸露的
except:
子句,则可能会捕获预期捕获的异常以外的异常-这可能会隐藏错误,或者在程序未按预期执行时使调试程序变得更加困难

例如,如果要将一行插入数据库,可能需要捕获一个异常,该异常指示该行已存在,以便进行更新

try:
    insert(connection, data)
except:
    update(connection, data)
如果指定了一个空的
,除了:
,还将捕获一个套接字错误,指示数据库服务器已崩溃。最好只捕获您知道如何处理的异常—程序在异常点失败通常比继续但以奇怪的意外方式运行要好

在一种情况下,您可能希望使用裸
,除了:
,它位于需要始终运行的程序的顶层,如网络服务器。但是,您需要非常小心地记录异常,否则就不可能找出哪里出了问题。基本上,一个程序中最多只能有一个地方可以这样做


所有这些的一个推论是,您的代码永远不应该执行
引发异常(“某些消息”)
,因为它强制客户机代码使用
除了:
(或者
除了异常:
,这几乎同样糟糕)。您应该针对要发出信号的问题定义一个异常(可能继承自一些内置异常子类,如
ValueError
TypeError
)。或者您应该引发一个特定的内置异常。这使代码的用户能够小心地捕获他们想要处理的异常。

这不适用于Python

例外的全部目的是尽可能接近问题的起因来处理问题

因此,您可以保留在异常情况下可能触发问题和解决方案的代码

问题是,您不可能知道一段代码可能引发的所有异常。您所能知道的就是,如果是一个假设文件未找到的异常,那么您可以捕获它,并提示用户获取一个执行或取消该功能的异常

如果你把try-catch放在这一点上,那么不管你的文件例程中有什么问题(只读、权限、UAC、不是真正的pdf等),每个人都会进入你的文件not-found-catch,你的用户会尖叫“但是它在那里,这代码是垃圾”

现在有两种情况,你可能会抓住一切,但它们应该被有意识地选择

它们是捕获、撤消某些本地操作(例如创建或锁定资源(例如打开磁盘上的文件进行写入),然后再次抛出异常,以便在更高级别上处理)

另一个是你不在乎为什么会出错。例如印刷。您可能有一个陷阱,就是说您的打印机有问题,请解决它,不要因为它而终止应用程序。如果您的代码使用某种计划执行一系列单独的任务,那么您不会希望整个任务都死掉,因为其中一个任务失败了


注意:如果您执行上述操作,我不能推荐某种类型的异常日志记录,例如,尝试使用catch log end,高度足够。

以下是我使用的位置,但不使用类型

  • 快速脏原型
  • 这是我的代码中未检查异常的主要用途

  • 顶级main()函数,其中记录每个未捕获的异常
  • 我总是添加这个,这样生产代码就不会溢出堆栈跟踪

  • 应用层之间
  • 我有两种方法:

    • 第一种方法是:当一个更高级别的层调用一个较低级别的函数时,它将调用封装在类型化的异常中,以处理“顶层”的较低级别异常。但我添加了一个泛型except语句,以检测低级函数中未处理的低级异常
    我更喜欢这种方式,我发现更容易检测哪些异常应该被正确捕获:当较低级别的异常被较高级别的异常记录时,我会更好地“看到”问题

    • 第二种方法:低层的每个顶层函数都有自己的代码wra
      try:
          insert(connection, data)
      except:
          update(connection, data)
      
      try:
          #code
      except ValueError:
          pass