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

geo*_*org 1 python package python-import python-2.7

我有一个实用程序模块utils.py,它使用请求来执行一些任务。在客户端代码(使用utils)中,我需要处理 引发的异常requests,但我想避免requests隐式导入(即在客户端中)。我怎样才能做到这一点?

utils.py是(简化)

 import requests

 def download(url):
     # stuff
     return requests.get(url)
Run Code Online (Sandbox Code Playgroud)

我希望client.py是这样的

 import utils  # <-- no "import requests"

 try:
      utils.download(whatever)
 except HTTPError:  # <-- not "requests.exceptions.HTTPError"
      do stuff
Run Code Online (Sandbox Code Playgroud)

except utils.something也会起作用的。该名称不需要是全局的。我想要的只是避免requests在客户的任何地方提及。

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

Gar*_*tty 5

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

当然,没有理由避免导入您想要使用的任何内容。这就是 Python 的工作方式、它的目的以及最好的工作方式。

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

def download(...):
    try:
        ...
    except HTTPError as e:
        raise DownloadError() from e
Run Code Online (Sandbox Code Playgroud)

编辑:

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

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

然而,我相信这可能更加脆弱 - 更不用说迂回和更难跟踪代码中的意图。我仍然强烈建议不要这样做。

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