简体   繁体   English

延迟加载模块导入__init__.py文件python中

[英]Lazy loading module imports in an __init__.py file python

I was wondering if anyone had any suggestions for lazy loading imports in an init file? 我想知道是否有人建议在init文件中延迟加载导入? I currently have the following folder structure: 我目前具有以下文件夹结构:

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

The init .py file in the core folder with the following imports: 核心文件夹中的init .py文件具有以下导入:

from mymodule import MyModule
from mymodule2 import MyModule2

This way I can just do: 这样我就可以做到:

from mypackage.core import MyModule, MyModule2

However, in the package init .py file, I have another import: 但是,在包init .py文件中,我还有另一个导入:

from core.exc import MyModuleException

This has the effect that whenever I import my package in python, MyModule and MyModule2 get imported by default because the core init .py file has already been run. 这样的效果是,每当我在python中导入包时,默认情况下都会导入MyModule和MyModule2,因为核心init .py文件已经运行。

What I want to do, is only import these modules when the following code is run and not before: 我想做的只是在运行以下代码时而不是之前导入这些模块:

from mypackage.core import MyModule, MyModule2

Any ideas? 有任何想法吗?

Many thanks. 非常感谢。

Unless I'm mistaking your intentions, this is actually possible but requires some magic. 除非我误会了您的意图,否则这实际上是可能的,但是需要一些魔术。

Basically, subclass types.ModuleType and override __getattr__ to import on demand. 基本上,子类为types.ModuleType并重写__getattr__以按需导入。

Check out the Werkzeug init .py for an example. 查看Werkzeug的init .py示例。

You can't. 你不能 Remember that when python imports it executes the code in the module. 请记住,当python导入时,它将执行模块中的代码。 The module itself doesn't know how it is imported hence it cannot know whether it has to import MyModule(2) or not. 模块本身不知道如何导入,因此不知道是否必须导入MyModule(2)

You have to choose: allow from mypackage.core import A, B and from core.exc import E does the non-needed imports (x) or do not import A and B in core/__init__.py , hence not allowing from mypackage.core import A, B . 您必须选择:允许from mypackage.core import A, B from core.exc import E不需要的导入(x) 不导入core/__init__.py AB ,因此不允许from mypackage.core import A, B导入from mypackage.core import A, B

Note: Personally I would not import MyModule(2) in core/__init__.py , but I'd add an all.py module that does this, so the user can do from mypackage.core.all import A, B and still have from mypackage.core.exc import TheException not loading the unnecessary classes. 注意:就我个人而言,我不会在core/__init__.py导入MyModule(2) ,但是我将添加一个all.py模块来执行此操作,因此用户可以from mypackage.core.all import A, B并仍然from mypackage.core.exc import TheException不会加载不必要的类。

(Actually: the all module could even modify mypackage.core and add the classes to it, so that following imports of the kind from mypackage.core import MyModule, MyModule2 work, but I think this would be quite obscure and should be avoided). (实际上是:在all模块甚至可以修改mypackage.core和类添加到它,所以, 那种进口from mypackage.core import MyModule, MyModule2工作,但我认为这将是非常模糊的,应该避免)。

Not sure if it applies here but in general lazy loading of modules can be done using the Importing package. 不确定它是否适用于此,但是通常可以使用Importing包来完成模块的延迟加载。

Works like this: 像这样工作:

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

Now my module is only really imported when you use it the first time. 现在,只有在您第一次使用我的模块时,它才真正导入。

If your modules structure is like: 如果您的模块结构如下:

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

or: 要么:

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

then feel free to use 然后随时使用

from mypackage.core import MyModule, MyModule2

without importing them in __init__.py under mypackage/core 而不将它们导入到mypackage/core下的__init__.py

You may use follow code in __init__ in module: 您可以在模块的__init__中使用跟随代码:

import apipkg
apipkg.initpkg(__name__, {
    'org': {
        'Class1': "secure._mypkg:Class1",
        'Class2': "secure._mypkg2:Class2",
    }
})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM