0

我有一个实用程序模块utils.py,它使用请求来执行一些任务。在客户端代码(使用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实现的以及它使用什么底层的底层库。

4

3 回答 3

5

简短的回答:你不能(或至少不应该)。

当然,没有理由避免导入您想要使用的任何内容。这就是 Python 的工作方式,旨在工作,并且工作得最好。

如果您真的想分离关注点,请download()捕获异常并抛出新utils.DownloadError异常。

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

编辑:

长答案:您实际上可以通过链式导入异常来做到这一点 - 但我强烈建议不要这样做 - 它只会使代码不那么清晰。

例如:如果你做from requests.exceptions import HTTPErrorin utils.py,那么你可以import utils使用utils.HTTPError.

然而,我相信这可能更脆弱——更不用说迂回和更难跟踪代码中的意图了。我仍然强烈反对它。

从关注点分离的角度来看 - 它可能会阻止你提及requests,但它仍然依赖于异常,所以它所做的只是隐藏关注点,而不是分离它。

于 2013-08-02T10:31:37.893 回答
1

我知道这是一种破旧的做法,但我会做以下两件事之一:

  • 处理 utils.py 中的异常或...
  • 注意 utils.py 中的异常,并在 requests.exceptions.HTTPError 的情况下重新引发 HTTPError

你会对这两个中的任何一个感到满意吗?

于 2013-08-02T11:05:06.370 回答
0

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

于 2013-08-02T10:35:33.397 回答