Skip to content

python dynamic import

lanzhiwang edited this page Dec 14, 2018 · 12 revisions

与模块相关的系统变量

  • sys.path
  • sys.modules
    • sys.modules是一个全局字典,该字典是python启动后就加载在内存中。每当导入新的模块,sys.modules都将记录这些模块。字典sys.modules对于加载模块起到了缓冲的作用。当某个模块第一次导入,字典sys.modules将自动记录该模块。当第二次再导入该模块时,python会直接到字典中查找,从而加快了程序运行的速度。字典sys.modules具有字典所拥有的一切方法,可以通过这些方法了解当前的环境加载了哪些模块。
  • __import__

动态导入的方法

方法一:

# 使用内置的 __import__() 函数

name = 'requests'
aa = __import__(name)
r= aa.get('http://www.baidu.com')
print(r.content)

方法二:

# 使用 importlib 模块

import importlib
name = "requests"
aa = importlib.import_module(name)
res = aa.get('http://www.baidu.com')
print(res.content)

动态导入示例

# bottle 框架使用的动态导入的方法

class _ImportRedirect(object):
    def __init__(self, name, impmask):
        """ Create a virtual package that redirects imports (see PEP 302). """
        self.name = name
        self.impmask = impmask
        self.module = sys.modules.setdefault(name, imp.new_module(name))
        self.module.__dict__.update({
            '__file__': __file__,
            '__path__': [],
            '__all__': [],
            '__loader__': self
        })
        sys.meta_path.append(self)

    def find_module(self, fullname, path=None):
        if '.' not in fullname: return
        packname = fullname.rsplit('.', 1)[0]
        if packname != self.name: return
        return self

    def load_module(self, fullname):
        if fullname in sys.modules: return sys.modules[fullname]
        modname = fullname.rsplit('.', 1)[1]
        realname = self.impmask % modname
        __import__(realname)
        module = sys.modules[fullname] = sys.modules[realname]
        setattr(self.module, modname, module)
        module.__loader__ = self
        return module

ext = _ImportRedirect('bottle.ext' if __name__ == '__main__' else
                      __name__ + ".ext", 'bottle_%s').module

def load(target, **namespace):
    """ Import a module or fetch an object from a module.

        * ``package.module`` returns `module` as a module object.
        * ``pack.mod:name`` returns the module variable `name` from `pack.mod`.
        * ``pack.mod:func()`` calls `pack.mod.func()` and returns the result.

        The last form accepts not only function calls, but any type of
        expression. Keyword arguments passed to this function are available as
        local variables. Example: ``import_string('re:compile(x)', x='[a-z]')``
    """
    module, target = target.split(":", 1) if ':' in target else (target, None)
    if module not in sys.modules: __import__(module)
    if not target: return sys.modules[module]
    if target.isalnum(): return getattr(sys.modules[module], target)
    package_name = module.split('.')[0]
    namespace[package_name] = sys.modules[package_name]
    return eval('%s.%s' % (module, target), namespace)
Clone this wiki locally