在Python3中构造模块异常的最佳实践 [英] Best practice for structuring module exceptions in Python3

查看:111
本文介绍了在Python3中构造模块异常的最佳实践的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个具有这样的文件夹结构的项目。

Suppose I have a project with a folder structure like so.

/project
    __init__.py
    main.py
    /__helpers
        __init__.py
        helpers.py
        ...

模块 helpers.py 定义一些异常并包含引发该异常的方法。

The module helpers.py defines some exception and contains some method that raises that exception.

# /project/__helpers/helpers.py

class HelperException(Exception):
    pass

def some_function_that_raises():
    raise HelperException

另一方面,我的 main.py 模块定义了自己的异常,并导入了可能从 helpers.py 引发异常的方法。

On the other hand my main.py module defines its own exceptions and imports methods that may raise an exception from helpers.py.

# /projects/main.py

from project.__helpers.helpers import some_function_that_raises

class MainException(Exception):
    pass

现在,我不希望用户必须 from project .__ helpers.helpers导入HelperException 如果他们想捕获该异常。能够从引发它的公共模块中导入异常会更有意义。

Now, I do not want users to have to do from project.__helpers.helpers import HelperException if they want to catch that exception. It would make more sense to be able to import the exception from the public module that is raising it.

但是我不能只移动 HelperException main.py ,这将创建循环导入。

But I cannot just move HelperException to main.py, which would create a circular import.

什么是最好的允许用户从 main.py 导入所有异常的方式,而那些在 / __ helpers 中引发的异常?

What would be the best way to allow users to import all exceptions from main.py while those being raised in /__helpers?

推荐答案

这是我想出的解决方案。

Here is the solution I came up with.

将所有异常放入一个文件中,从中可以将它们导入,然后将它们全部导入到 main.py 中。为了使所有内容清晰明了,我们最终定义模块的 __ all __ 属性。

The idea is basically to put all the exceptions in one file from which they can be imported and then import them all in main.py. To make everything clean and explicit, we finally define the __all__ attribute of the module.

这是新文件结构

/project
    __init__.py
    main.py
    /__helpers
        __init__.py
        exceptions.py
        helpers.py
        ...

这是 exceptions.py 文件。

# /project/__helpers/exceptions.py

class MainException(Exception):
    pass

# Note that this also allows us to inherit between exceptions
class HelperException(MainException):
    pass

然后我们可以从该文件中导入异常而没有风险

Then we can import exceptions from that file without risk of circular dependency.

最后,我们在 main.py __ all __ c $ c>明确指出要导入异常。

And finally we define __all__ in main.py to make it explicit that the exceptions are to be imported.

# /projects/main.py

from project.__helpers.helpers import some_function_that_raises
from project.__helpers.exceptions import MainException, HelperException

__all__ = ['MainException', 'HelperException', ...]

仅提醒一下, __ all __ 属性定义了如果导入了从项目导入中完成 * 。因此,这都将所需的行为扩展到导入星标,并明确表明我们希望异常

Just a reminder the __all__ attribute defines what will be imported if one was to do from project import *. So this both extends the desired behavior to import star and makes it explicit that we want the exceptions to be imported from that file.

还要注意,某些IDE甚至会将'HelperException'放在<$ c中$ c> __ all __ 作为对 HelperException 的引用,不会打扰您使用未使用的导入。这就是让我认为这是正确的方法。

Also note that some IDEs will even treat 'HelperException' being in __all__ as a reference to HelperException and will not bother you from having an unused import. This is what leads me to think this is the correct approach.

这篇关于在Python3中构造模块异常的最佳实践的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆