gpt4 book ai didi

python - 使用 importlib.import_module 处理导入模块引发的异常

转载 作者:行者123 更新时间:2023-12-01 07:07:54 24 4
gpt4 key购买 nike

我有一个简单的插件系统,简化形式如下。想法是插件将实现一个抽象类,并可以引发异常来发出拆卸信号。

# my_plugin.py
import my_app


class MyPlugin(my_app.MyPluginBase):

def start(self):
raise my_app.MyLibException()
# my_app.py
import abc
import importlib


class MyLibException(Exception):
pass


class MyPluginBase(abc.ABC):

@abc.abstractmethod
def start(self):
pass


def main():
module = importlib.import_module('my_plugin')
klass = getattr(module, 'MyPlugin')
try:
app = klass()
app.start()
except MyLibException as e:
print('ok')
print(e.__class__)
except Exception as e:
print('not ok')
print(e.__class__)


if __name__ == '__main__':
main()

运行以上结果:

not ok
<class 'my_app.MyLibException'>

在这种情况下处理异常的正确方法是什么?我想捕获这里引发的异常 except MyLibException as e: 而不是 except Exception as e:

最佳答案

问题的根本原因是MyLibExceptionmy_app.py中被识别为__main__的属性,但是在导入时my_plugin.py 它是 my_app 的一个属性。

最干净的解决方案是将 MyLibException 与其他模块分开,以避免完全循环依赖,但既然您在评论中提到这不是一个选项,我能想到的唯一方法是通过在同一文件中导入异常。这显然不是一个好的做法,但对于一般的循环导入来说也是如此。

实现这一点的几种方法是:

  1. 通过添加 import my_app (或 import __main__ as my_app)my_app.py 并使用 except my_app.MyLibException

    捕获异常
  2. 通过使用 importlib 就像导入 my_plugin 一样:my_app = importlib.import_module('my_app')并以与1相同的方式捕获。

  3. from __main__ import MyLibException 在定义 MyLibException 之后,但这违反了 PEP8其中指出:

    Imports are always put at the top of the file, just after any module comments and docstrings, and before module globals and constants.

有关更多建议以及这可能不是一个好主意的原因,另请参阅:

关于python - 使用 importlib.import_module 处理导入模块引发的异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58357892/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com