Python和例外

时间:2011-06-08 18:55:21

标签: python exception

来自Java背景,当我被警告我没有捕获异常时,我喜欢它,而不必阅读文档。如果我确实阅读了有关方法的文档,则抛出的异常会在文档的方法签名中显示。

使用Python我必须经常阅读文档中的一段文字,找到一个句子,说明将抛出什么异常。

另外,我今天在Python中使用了第三方库http://packages.python.org/kombu/reference/kombu.connection.html,这激怒了我。没有标准的文档格式?我使用的是通道方法(http://packages.python.org/kombu/reference/kombu.connection.html#kombu.connection.BrokerConnection.channel),它甚至没有声明它会引发异常。我必须通过反复试验找到这个。

我在这里遗漏了一些明显的东西,或者在Python及其文档中将异常视为事后的想法。

5 个答案:

答案 0 :(得分:14)

我们例外。它们是非常重要的语言功能。好的文档通常会说明在哪些情况下会抛出什么异常,而且我个人发现大多数文档在这方面都很好。当然,总有一定比例的文档不好。无论哪种方式,如果你正在为每个功能寻找一个明确的独立列表,那你就不走运了。除了编写代码的程序员之外,没有人知道这一点。

阅读段落对我来说听起来不是太糟糕,特别是因为段落的信息通常非常重要。然后是<Ctrl+F>raises<Enter> ...

  

没有标准的文档格式?

有许多项目使用的Sphinx(包括docs.python.org,因此您已经知道它;并且还包括您链接到的项目,尽管它使用不同的光学样式)。当然,没有人可以强制每个项目都使用它,就像你不能强迫它们使用标准的编码风格一样。但老实说,我认为除了两个(PyGame和LEPL)使用Sphinx之外,我目前使用的所有项目。这可能是因为我需要使用相对较少的文档库,但仍然可以使用。

  

当我被警告我没有发现异常时,我喜欢它

为什么呢?粗略猜测,60%的初学者获得的例外是因为他们没有正确编码,而不是因为需要处理的一些特殊的环境状态。例如,TypeErrorImportError根本不会出现在无错编写的程序中(保存元编程和需要极端动态的部分)。

通常,如果您希望编译器告诉您有关您尚未了解的代码的信息,那么您使用的是错误的语言。 Python是动态的,你测试而不是静态分析。处理它。

答案 1 :(得分:6)

Bruce Eckel discusses Java详细检查了异常与Python异常。关键报价:

  

当我开始使用Python时,所有的   出现例外情况,没有例外   不小心“消失了”。如果你   想要捕捉异常,你可以,   但你不是被迫写钱   代码一直都是   传递例外。他们去   到达你想要捕捉它们的地方,或者   如果你忘了,他们会一直走出去   (因此他们提醒你)但他们   不要消失,这是最糟糕的   所有可能的情况。我现在相信   检查异常鼓励人们   让他们消失。而且他们做得很多   代码不太可读。

值得阅读整篇文章。

关于文档,我说是的,有些文档很糟糕。

答案 2 :(得分:5)

Python对声明Java所做的异常没有相同的要求。大多数语言没有。就此而言,Java通常会抛出未立即声明的异常(NullPointerException任何人?)。记录所有语言中的异常是礼貌的,但在一个我们甚至无法保证甚至会记录公共方法的世界中,这真的令人惊讶吗?

查看您正在使用的库,看起来您需要实例化一个Transport对象(真正引发Exception的东西)确实有一个抛出的异常列表。这是抛出异常的真实对象,而不是BrokerConnection。

你知道traceback模块吗?它可能会帮助您在将来追踪这些问题。

答案 3 :(得分:0)

我认为这是一个透视问题。 Java系统有它自己的错误。例如,在Java中的大部分时间我发现我只是在编写printStackTrace。有时,我需要做一些更复杂的事情。例如,系统需要将错误消息打印到通过telnet连接的用户。再次,有大量的样板。

这就是为什么喜欢python让你定义一个函数来捕获所有未捕获的异常的原因:sys.excepthook。当然,这附带了它自己的一系列问题,但我喜欢它,如果我需要它的功能就在那里。

答案 4 :(得分:0)

虽然我无法保证您所提到的第三方库的使用经验,但我要说至少会有关于例外情况的文档。以内置smtplib为例。解释了可以抛出的异常,并且方法包括有关它们将抛出哪些以及原因的信息。

至于提前知道可以抛出什么异常,无论你是否未能解释等等 - 你可能会在IDE中找到一些代码内省,它会为你提供你所追求的东西。

根据我的经验,例外情况要么是你知道提前知道的事情,因为你有无法控制的设置条件(处理用户输入等),或者你使用以规则的方式封装行为的方法操作他们出去了。例如,在Python中,如果您正在使用具有给定属性的Object,但您不确定是否可以保证具有此属性,而不是打电话给Object.method()而是改为:

# getattr uses the arguments (object, 'attribute', default)
toCall = getattr(MyInstance, 'methodName', None)

if toCall is not None:
  toCall(args)

# or if you prefer
if toCall is None:
  myDialogClass.NotifyUser('Object does not contain necessary method.')

使用字典等集合时,更容易:

nums = dict((i, i) for i in range(30))

# Here the .get() method takes the form (key, default)
# No such thing as a KeyError 
nums.get('50', None)

所以,通常,当你讨论python编程时,你的想法并不是要确保每个例外都要考虑到。恰恰相反。考虑你必须使用的那些,但使用成语来编程,以尽量减少你必须处理的数量。