gpt4 book ai didi

python - 我应该什么时候声明自定义异常?

转载 作者:太空狗 更新时间:2023-10-29 21:51:16 25 4
gpt4 key购买 nike

我想引发异常来传达一些消息和与错误相关的值。我想知道什么时候声明自定义异常与使用内置异常最合适。

我见过很多像 this 这样的例子以及其他网站上推荐的更多内容。

class NameTooShortError(ValueError):
pass

def validate(name):
if len(name) < 10:
raise NameTooShortError(name)

我更倾向于编写如下代码:

def validate(name):
if len(name) < 10:
raise ValueError(f"Name too short: {name}")

如果需要在异常实例中存储复杂或特定信息,我的直觉是只声明自定义异常。声明空类对我来说似乎是错误的。

最佳答案

有两个问题合而为一:我应该多久使用一次自定义异常(不要过度使用它们)?我真的应该更喜欢自定义异常(而不是内置异常)吗? 让我们来回答这两个问题。

过度使用自定义异常

您链接的 Dan Bader 的博客文章是一个很好的例子,说明了不应该这样做。过度使用自定义异常的示例。每个异常类都应该涵盖一组相关用途(ConfigError、BrowserError、DateParserError)。您绝对不应该为需要提出问题的每种特定情况创建新的自定义异常。这就是异常消息的用途。

自定义与内置异常

这是一个更基于意见的主题,它也高度依赖于特定的代码场景。我将展示两个有趣的示例(可能有很多),我认为在这些示例中使用自定义异常是有益的。

01:内部曝光

让我们创建一个简单的 Web 浏览器模块(围绕 Requests 包的薄包装):

import requests

def get(url):
return requests.get(url)

现在假设您想在包中的多个模块中使用新的网络浏览器模块。在其中一些中,您想捕获一些可能的网络相关异常:

import browser
import requests

try:
browser.get(url)
except requests.RequestException:
pass

此解决方案的缺点是您必须在每个模块中导入 requests 包才能捕获异常。您还公开了浏览器模块的内部结构。如果您决定将底层 HTTP 库从 Requests 更改为其他内容,则必须修改您捕获异常的所有模块。捕获一些一般异常的替代方法也是 discouraged .


如果您在网络浏览器模块中创建自定义异常:

import requests

class RequestException(requests.RequestException):
pass

def get(url):
try:
return requests.get(url)
except requests.RequestException:
raise RequestException

那么您所有的模块现在都将避免上述缺点:

import browser

try:
browser.get(url)
except browser.RequestException:
pass

请注意,这也是 Requests 包本身使用的方法 - 它定义了自己的 RequestException 类,因此您不必导入底层的 urllib 包在您的网络浏览器模块中只是为了捕获它引发的异常。

02:阴影错误

自定义异常不仅仅是为了让代码更漂亮。查看您的代码(稍微修改过的版本)以发现一些非常邪恶的东西:

def validate(name, value):
if len(name) < int(value):
raise ValueError(f"Name too short: {name}")

return name

现在有人会使用你的代码,但他宁愿捕获它并提供一个默认名称,而不是在短名称的情况下传播你的异常:

name = 'Thomas Jefferson'

try:
username = validate(name, '1O')
except ValueError:
username = 'default user'

代码看起来不错,不是吗?现在看这个:如果您将 name 变量更改为任何字符串,则 username 变量将始终设置为 'default user'。如果您定义并引发自定义异常 ValidationError,则不会发生这种情况。

关于python - 我应该什么时候声明自定义异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57165380/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com