【问题标题】:Correct way to re-export modules from __init__.py从 __init__.py 重新导出模块的正确方法
【发布时间】:2020-06-11 22:07:07
【问题描述】:

我有一个 plugins 包,其中包含多个模块,每个模块定义一个类(每个类都是一个 插件)。

我的包结构如下:

plugins
├ __init__.py
├ first_plugin.py
├ second_plugin.py
└ third_plugin.py

一个插件文件通常看起来像这样,只包含一个类定义(必要时还有一些导入):

# in first_plugin.py

class MyFirstPlugin:
    ...

我希望最终用户能够像这样导入插件:

from plugins import FirstPlugin

而不必输入模块名称(这是当前需要做的):

from plugins.first_plugin import FirstPlugin

有没有办法通过直接在 __init__.py 文件中重新导出模块的类来实现这一点而不必像这样逐个模块地导入所有模块(当有很多时这会变得很麻烦模块):

# in __init__.py

from .first_plugin import FirstPlugin
from .second_plugin import SecondPlugin
from .third_plugin import ThirdPlugin

【问题讨论】:

  • 由于您所有的插件都在一个包中,我对How to import members of all modules within a package? 的回答可能会有所帮助。
  • 我也有同样的问题。只是想知道您是否发现并找到了解决方案?
  • 我真的没有找到任何令人满意的东西......我想我有一些使用 dir() 并按模块名称过滤的“黑客”想法(可以作为 str 访问Python),但它很快就会变脏。

标签: python python-3.x python-import


【解决方案1】:

我认为这在 Python 中是不可能的。但是,您可以导入整个模块,因此您不必单独导入每个类。

例如

from first_plugin import *

允许你做

from plugin import # Anything in first_plugin

这有点痛苦,但编写库并不容易(等到你用 C/C++ 使用 CMake,你必须指定 every single 文件 在你的源代码树中:D)

【讨论】:

  • 我认为导入整个插件的语法(同时仍然简化路径)相当from first_plugin import *,不是吗?使用您的语法,我相信您仍然必须输入from plugins.first_plugin import ... 对吗?
  • 废话,对不起,我累了,我编辑它以添加它。此外,如果您想使用 * 从库中导入所有内容,您应该定义一个名为 __all__ 的列表,其中模块名称将使用 * 自动导入
【解决方案2】:

我认为您可以详细说明这篇文章的答案:How to import all submodules?

例如使用pkgutil.walk_packages(__path__),您将拥有一个模块列表。然后你可以在加载的模块上使用dir并导入结果(过滤以__开头的元素

【讨论】:

  • 但如果我没记错的话,那仍然只会导入子模块,而我想导入子模块中定义的类。
  • 如果您在模块上使用 dir,那么您将拥有类的名称。我很确定你可以用他们的名字导入它们。我现在不能尝试,但如果您在那之前还没有弄清楚,我会在明天尝试。
猜你喜欢
  • 2017-03-12
  • 2015-07-30
  • 2016-06-14
  • 2015-08-17
  • 1970-01-01
  • 2019-12-03
  • 1970-01-01
  • 2013-07-29
  • 1970-01-01
相关资源
最近更新 更多