我有以下包结构
next()
我希望能够package
__init__.py
sub1
__init__.py
foo.py # Contains class Foo
sub2
__init__.py
bar.py # Contains class Bar
并拥有import package
和package.Foo
,即我希望子包对用户透明。
问题在于导入sub2需要很长时间,并且许多用户根本不关心sub2中的内容并且只想要sub1中的内容。因此,我希望用户能够说出package.Bar
或import 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中都有效,但如果两者都不可能,我会接受其中一个。
答案 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