Python导入一个没有其他子包的子包

时间:2015-10-31 13:23:58

标签: python packages python-import python-module

我有以下包结构

next()

我希望能够package __init__.py sub1 __init__.py foo.py # Contains class Foo sub2 __init__.py bar.py # Contains class Bar 并拥有import packagepackage.Foo,即我希望子包对用户透明。

问题在于导入sub2需要很长时间,并且许多用户根本不关心sub2中的内容并且只想要sub1中的内容。因此,我希望用户能够说出package.Barimport package.sub1只需导入sub1并跳过sub2的导入。

我知道我可以通过from package import sub1包含

来实现第一部分
package/__init__.py

并且from .sub1 import * from .sub2 import * package/sub1/__init__.py,对于sub2也是如此。但是,即使用户尝试仅导入from .foo import Foo,也会导入sub1和sub2。

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

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

2 个答案:

答案 0 :(得分:4)

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 +

中执行它的官方方式

答案 1 :(得分:0)

您可以将快捷方式添加到模块的__init__.py

<强>包/ __初始化__。PY

__all__ = [
    ... add everything you want to be listed for this module
    'Foo',
    'Bar',
    ...
]
from package.sub1.foo import Foo
from package.sub2.bar import Bar

现在您应该可以致电:

from package import Bar