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

时间:2018-01-04 23:08:03

标签: python python-3.x exception circular-dependency

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

/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。能够从提升它的公共模块导入异常会更有意义。

但我不能只将HelperException移到main.py,这会创建一个循环导入。

允许用户在main.py中引发/__helpers时引导 btnLaunchMyProgram.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { File file1 = new File("C://Users//" + System.getProperty("user.name") + "//Desktop//My Program//myprogram.exe"); if(!file1.exists()) { try { HttpDownloadUtility.downloadFile("https://www.example.com/downloads/MyProgram.exe", "C://Users//" + System.getProperty("user.name") + "//Desktop//My Program//"); } catch (IOException e) { e.printStackTrace(); } } try { Process p = Runtime.getRuntime().exec(new String[] {"cmd.exe", "\"" + "C://Users//" + System.getProperty("user.name") + "//Desktop//My Program//MyProgram.exe" + "\""}); } catch (IOException e) { e.printStackTrace(); } } }); 的所有例外的最佳方法是什么?

1 个答案:

答案 0 :(得分:0)

这是我提出的解决方案。

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

这是新的文件结构

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

以下是error.py文件。

# /project/__helpers/error.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.errors import MainException, HelperException

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

只需提醒一下,__all__属性定义了如果要执行from project import *将导入的内容。因此,这会将所需行为扩展到import star,并明确表示我们希望从该文件导入异常。

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