我为我的一个项目定义了一些自定义异常。很多方面可以使用标准的Python异常(例如ZeroDivisionError),而不需要import
,有什么方法可以设置我的项目让我的自定义异常暴露给我的一个包中的所有文件?
Python将所有内置异常类型放入builtins
模块中。所以,无论你在哪里评价ZeroDivisionError
,都可以找到它
你的例外不在builtins
中,它们在你定义的任何模块中。因此,它们必须作为mymodule.MyError
访问,或者用from mymodule import MyError
之类的东西进行访问。
此外,正如N. Chauhan在a comment中指出的那样,你很少需要一些公共异常类型 - 通常只有一种。您可能有30种不同的错误类型在内部,但您的用户可能只关心1或2种不同类型的错误,因此您可以使30种类型的所有子类都包含1或2个基类,而您的用户只需要import
那些。
你能做同样的伎俩吗?是的,它实际上很容易 - 但它几乎总是一个坏主意。
听起来这对于REPL的交互式编程来说会很方便 - 但在那里不需要它。只需在当前(__main__
)模块中添加新内容,它就像在builtins
中一样可以访问,对吗? Python为此提供了语法糖。事实上,这正是from mymodule import MyError
所做的:它将MyError
添加到当前模块的全局变量中。
对于非交互式编程,将内容放入内置函数会使代码混乱且难以阅读。
如果我在某些代码中看到MyError
,并且在顶部看到from mymodule import MyError
,那么很明显它来自哪里。如果我不这样做,那么就无法找出MyError
的来源,除非详尽地搜索整个代码库以及任何地方导入的所有站点包模块。
而IDE和其他工具更难以帮助您编写和导航代码。如果我将鼠标悬停在PyCharm的MyError
上,并且顶部有一个from mymodule import MyError
,PyCharm会立即知道它来自哪里,并且可以显示一个很好的工具提示,其中包含任何有用的信息。我可以右键单击它,它可以跳转到MyError
的定义。如果我启用静态类型检查,它知道MyError
是什么,并可以验证它是Exception
的子类。等等。但没有那个import
,PyCharm就不可能知道MyError
的含义。
1.当您评估ZeroDivisionError
时,其工作方式的过度简化版本是,如果它不是本地变量或自由变量,Python会在全局变量中查找它,如果它不存在,则在内置变量中查找。 (有关更深入的解释,请参阅eval
and exec
文档,有关详细信息,请参阅Resolution of names。)
你是怎么做到的?您可以将不同的builtins
模块替换为碰巧包含额外内容的全局变量,但真正简单的方法是只需要import builtins
并添加新内容,例如builtins.MyError = MyError
。