2

我想知道是否有人对在初始化文件中延迟加载导入有任何建议?我目前有以下文件夹结构:

/mypackage
    __init__.py
    /core
        __init__.py
        mymodule.py
        mymodule2.py

核心文件夹中的init .py 文件具有以下导入:

from mymodule import MyModule
from mymodule2 import MyModule2

这样我就可以做到:

from mypackage.core import MyModule, MyModule2

但是,在包init .py 文件中,我有另一个导入:

from core.exc import MyModuleException

这样做的效果是,每当我在 python 中导入我的包时,默认情况下都会导入 MyModule 和 MyModule2,因为核心init .py 文件已经运行。

我想要做的只是在运行以下代码而不是之前导入这些模块:

from mypackage.core import MyModule, MyModule2

有任何想法吗?

非常感谢。

4

6 回答 6

6

除非我误解了你的意图,否则这实际上是可能的,但需要一些魔法。

基本上,子类化types.ModuleType和覆盖__getattr__以按需导入。

以 Werkzeug init .py为例。

于 2013-08-15T22:06:28.803 回答
3

你不能。请记住,当 python 导入时,它会执行模块中的代码。模块本身不知道它是如何导入的,因此它不知道它是否必须导入MyModule(2)

您必须选择:允许from mypackage.core import A, B from core.exc import E执行不需要的导入 (x)不导入Aand Bin core/__init__.py,因此不允许from mypackage.core import A, B.

注意:我个人不会 import MyModule(2)in core/__init__.py,但我会添加一个all.py执行此操作的模块,因此用户可以这样做from mypackage.core.all import A, B 并且仍然from mypackage.core.exc import TheException没有加载不必要的类。

(实际上:all模块甚至可以修改mypackage.core并向其添加类,以便后续导入此类from mypackage.core import MyModule, MyModule2工作,但我认为这将非常晦涩,应该避免)。

于 2013-07-09T11:32:26.080 回答
1

如果您的模块结构如下:

/mypackage
  __init__.py
  /core
    __init__.py
    MyModule.py
    MyModule2.py

或者:

/mypackage
  __init__.py
  /core
    __init__.py
    /MyModule
      __init__.py
    /MyModule2
      __init__.py

然后随意使用

from mypackage.core import MyModule, MyModule2

__init__.py没有在下面导入它们mypackage/core

于 2013-07-09T10:59:45.117 回答
1

不确定它是否适用于此,但通常可以使用Importing包完成模块的延迟加载。

像这样工作:

from peak.util.imports import lazyModule
my_module = lazyModule('my_module')

现在我的模块只有在你第一次使用时才真正导入。

于 2015-07-15T12:23:42.600 回答
1

您可以在模块的 __init__ 中使用以下代码:

import apipkg
apipkg.initpkg(__name__, {
    'org': {
        'Class1': "secure._mypkg:Class1",
        'Class2': "secure._mypkg2:Class2",
    }
})
于 2015-10-05T16:26:33.083 回答
0

我意识到这个问题是很久以前发布的,从那以后有一些有用的更新来解决延迟加载子模块。因此,对于寻找如何解决此问题的其他人,我们现在提供了很好的选择。

特别是 PEP 562

以下是那篇文章的摘录:

getattr的另一个广泛用例是惰性子模块导入。> 考虑一个简单的例子:

# lib/__init__.py
import importlib

__all__ = ['submod', ...]

def __getattr__(name):
    if name in __all__:
        return importlib.import_module("." + name, __name__)
    raise AttributeError(f"module {__name__!r} has no attribute {name!r}")


# lib/submod.py
print("Submodule loaded")
class HeavyClass:
    ...


# main.py
import lib
lib.submod.HeavyClass  # prints "Submodule loaded"
于 2021-09-06T21:33:18.687 回答