在“验证”类中使用异常还是返回状态码更好?

9 投票
2 回答
2129 浏览
提问于 2025-04-16 03:52

假设我正在创建一个类,用来验证一个号码,比如美国的“社会安全号码”(这只是一个国家身份证明的例子)。这个号码有一些规则需要验证,这些规则是从网站上的一个HTML表单输入的。

我想用Python创建一个简单的类,并设计一个公共的 validate 方法。这个 validate 方法会返回 TrueFalse,非常简单。这个方法会调用其他一些小的私有方法(比如针对前面几个数字有不同的规则),每个方法也会返回 TrueFalse

因为这个过程真的很简单,所以我打算只使用布尔状态码(就是判断是否有效,不需要详细的错误信息)。

我最近在阅读一些关于使用异常的文章,我想知道在我的情况下,使用异常是否是个好主意?

2 个回答

11

这个问题虽然很老,但因为之前的回答在我看来不适用于Python,所以我来分享一下我的看法。


对于很多刚接触Python的程序员来说,处理异常(错误)是一个比较困难的事情。和其他编程语言相比,Python在使用异常方面有很大的不同:实际上,Python经常用异常来控制程序的流程

一个经典的例子就是 for 循环:你一定同意,当循环完成所有的迭代时,这并没有什么“特别奇怪”的地方(实际上,所有循环都是这样,除非被中断)……然而,Python并不会提前检查是否还有值可以处理,而是继续尝试从可迭代对象中读取值,如果失败了,就会抛出一个 StopIteration 异常,这个异常会被 for 循环捕获,从而让代码退出循环。

此外,在Python中,使用EAFP(即“请求原谅比请求许可更简单” = try-except)是很常见的,而不是LBYL(即“跳跃前先看” = if not A, B or C then)。

在这方面,csj的回答对于C或Java是正确的,但对Python来说就不太相关了(因为Python的异常很少是“特殊”的)。

还有一个需要考虑的因素是,当用户输入的数据无效,但你没有根据验证函数的结果采取行动时,会发生什么:

  • 如果使用 return 语句,未能处理 False 值将导致无效数据继续传递下去,
  • 相反,如果你抛出一个异常,未能捕获这个异常将导致异常在你的代码中传播,最终使代码停止运行。

虽然第二种选择一开始看起来有点可怕,但这仍然是正确的做法:如果数据无效,就没有必要继续传递下去……这很可能会在后面的流程中引入难以追踪的错误,而且你也会错过修复代码中的错误的机会(未能对无效数据采取行动)。

再说一次,使用异常是Pythonic的做法(但这不适用于大多数其他语言),这在另一个回答Python之禅中也有提到:

错误不应该默默无闻地过去。

除非被明确地抑制。

希望这对你有帮助!

7

如果输入要么是有效的,要么是无效的,那就直接返回一个真假值(true或false)。遇到无效值的验证测试并没有什么特别的地方。

撰写回答