使用模块中的异常而不显式导入它

2024-03-28 04:08:45 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个实用模块utils.py,它使用requests执行一些任务。在客户机代码(使用utils)中,我需要处理requests引发的异常,但我希望避免隐式导入requests(即在客户机中)。我怎样才能做到这一点?你知道吗

utils.py是(简化的)

 import requests

 def download(url):
     # stuff
     return requests.get(url)

我希望client.py像这样

 import utils  # <-- no "import requests"

 try:
      utils.download(whatever)
 except HTTPError:  # <-- not "requests.exceptions.HTTPError"
      do stuff

except utils.something也可以。名称不需要是全局的。我只想避免在客户端的任何地方提到requests。你知道吗

对于那些想知道的人来说,这只是一个关注点分离的问题。client.py不应该关心utils.download到底是如何实现的,以及它使用的底层库是什么。你知道吗


Tags: 模块代码pyimportclienturl客户机return
3条回答

简而言之:你不能(或者至少不应该)。你知道吗

当然,没有理由不导入任何你想使用的东西。这就是Python的工作方式、目的和最佳工作方式。你知道吗

如果确实要分离关注点,请使download()捕获异常,并抛出一个新的utils.DownloadError异常。你知道吗

def download(...):
    try:
        ...
    except HTTPError as e:
        raise DownloadError() from e

编辑:

长话短说:实际上,您可以通过链导入异常来做到这一点——但我强烈建议您不要这样做——它只会使代码变得不那么清晰。你知道吗

例如:如果你在utils.py中做from requests.exceptions import HTTPError,那么你可以import utils并使用utils.HTTPError。你知道吗

然而,我相信,这可能更脆弱——更不用说迂回,更难以追踪代码中的意图。我还是强烈反对。你知道吗

从关注点分离的角度来看,它可能会阻止您提到requests,但它仍然依赖于异常,因此它所做的只是隐藏关注点,而不是将其分离。你知道吗

我知道这是一种卑鄙的做法,但我愿意做两件事中的一件:

  • 处理内部异常实用程序.py或者。。。你知道吗
  • 请注意实用程序.py并在出现错误时重新引发HTTPErrorrequests.exceptions.HTTPError错误你知道吗

你对这两个人中的任何一个满意吗?你知道吗

您可以使用utils.requests.exceptions.HTTPError,但不能避免“提及”requests。你所能做的就是以一种迂回的、容易出错的方式提及它。你知道吗

相关问题 更多 >