在Python3中构造模块异常的最佳实践

奥利维尔·梅兰松(OlivierMelançon):

假设我有一个带有文件夹结构的项目。

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

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

# /project/__helpers/helpers.py

class HelperException(Exception):
    pass

def some_function_that_raises():
    raise HelperException

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

# /projects/main.py

from project.__helpers.helpers import some_function_that_raises

class MainException(Exception):
    pass

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

但我不能只是移动HelperExceptionmain.py,这将创建一个圆形进口。

允许用户从中main.py引发异常的最佳方式/__helpers什么?

奥利维尔·梅兰松(OlivierMelançon):

这是我想出的解决方案。

这个想法基本上是将所有异常放入一个文件中,从中可以导入它们,然后将它们全部导入main.py为了使所有内容清晰明了,我们最终定义__all__了模块属性。

这是新的文件结构

/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

然后,我们可以从该文件导入异常,而没有循环依赖的风险。

最后,我们定义__all__main.py,清楚的例外是进口。

# /projects/main.py

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

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

只是提醒一下,该__all__属性定义了要执行的操作将要导入的内容from project import *因此,这既扩展了导入星号所需的行为,又明确表明我们希望从该文件中导入异常。

另请注意,某些IDE甚至会将'HelperException'__all__当作in 的引用,HelperException并且不会打扰您使用未使用的导入。这就是让我认为这是正确的方法的原因。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章