Python只导入一个子包而不导入其他子包

标签 python package python-import python-module

我有如下包结构

package
    __init__.py
    sub1
        __init__.py
        foo.py      # Contains class Foo
    sub2
        __init__.py
        bar.py      # Contains class Bar

我希望能够只import package 并拥有package.Foopackage.Bar,即我想要子包对用户透明。

问题是导入sub2需要很长时间,很多用户根本不关心sub2里的东西,只想要sub1里的东西。因此,我希望用户能够说import package.sub1from package import sub1just import sub1 并跳过sub2 的导入。

我知道我可以通过包含 package/__init__.py 来实现第一部分

from .sub1 import *
from .sub2 import *

并且 package/sub1/__init__.pyfrom .foo import Foo 和 sub2 类似。但是,这将始终导入 sub1 和 sub2,即使用户尝试仅导入 package.sub1

相应地,我可以通过让 package/__init__.py 为空并使用与上面相同的 sub1/__init__.py 来实现第二部分。但是,只是说 import package 不会加载 sub1 或 sub2,因此用户必须显式加载它们,然后引用 package.sub1.Foo

理想情况下,一个解决方案在 2.7.10 和 3.5.0 中都适用,但如果两者都不可能,我会接受一个或另一个。

最佳答案

LazyLoader类正是为这种情况提供的:在实际使用模块时推迟加载模块,而不是在导入模块时。

要构建延迟加载器,您可以按照文档中的示例进行操作:

suffixes = importlib.machinery.SOURCE_SUFFIXES
loader = importlib.machinery.SourceFileLoader
lazy_loader = importlib.util.LazyLoader.factory(loader)
finder = importlib.machinery.FileFinder(path, [(lazy_loader, suffixes)])

然后你可以使用finder.find_spec获取模块的规范并将结果传递给Loader.create_module加载它。

仅对一个模块手动操作有点麻烦。

请注意,搜索“lazy import python”,您会发现很多解决方案各有利弊,其中一些在 python2.x 中运行。然而,上面的 LazyLoader 类是 python3.5+ 中的官方方式

关于Python只导入一个子包而不导入其他子包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33452096/

相关文章:

python-3.x - 从 setup.py 中的包导入脚本

python - 检查符号 NaN 是否为字符串或 python 缺失值保留符号

java - 选择性 jar 装

python - flask - AttributeError : 'module' object has no attribute 'items'

python - caffe 安装找不到 python 3.5,即使它已安装并在路径变量中标记

python - 在 matplotlib 中绘制 Needleman-Wunsch 成对序列比对的得分矩阵

java - java包名为什么要小写?

oracle - 'ORA-01031 : insufficient privileges' error received when inserting into a View

Python 函数引用

python - 如何使用 get_object_or_404 和 order_by ('?' ) 来获取随机图像