原文出处: koala bear   

Direct use of __import__() is rare, except in cases where you want to import a module whose name is only known at runtime.

本文介绍 python module 的动态加载,我们有时希望从配置文件等地获取要被动态加载的 module,但是所读取的配置项通常为字符串类型,无法用 import 加载,例如:

 
>>> import 'os'
File "<stdin>", line 1
import 'os'
^
SyntaxError: invalid syntax
1
2
3
4
5
6
>>> import 'os'
File "<stdin>", line 1
import 'os'
^
SyntaxError: invalid syntax
 

Python 提供内建函数 __import__ 动态加载 module,__import__ 的用法如下:

 
__import__ (name[, globals[, locals[, fromlist[, level]]]])
1
2
__import__ (name[, globals[, locals[, fromlist[, level]]]])
 
  • name (required): 被加载 module 的名称
  • globals (optional): 包含全局变量的字典,该选项很少使用,采用默认值 global()
  • locals (optional): 包含局部变量的字典,内部标准实现未用到该变量,采用默认值 local()
  • fromlist (Optional): 被导入的 submodule 名称
  • level (Optional): 导入路径选项,默认为 -1,表示同时支持 absolute import 和 relative import
 
>>> os_module = __import__('os')
>>> print os_module.path
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
1
2
3
4
>>> os_module = __import__('os')
>>> print os_module.path
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
 

事实上,import 本质上是调用 __import__ 加载 module 的,比如:

 
import foo

最终调用如下函数实现

foo = __import__('foo', globals(), locals(), [], -1)

1
2
3
4
5
6
import foo
 
最终调用如下函数实现
 
foo = __import__('foo', globals(), locals(), [], -1)
 

但如果使用不善,也容易踩坑:

 
>>> __import__("os")
<module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>

>>> __import__("os.path")
<module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>

1
2
3
4
5
6
>>> __import__("os")
<module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
 
>>> __import__("os.path")
<module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
 

如果输入的参数如果带有 “.”,采用 __import__ 直接导入 module 容易造成意想不到的结果。 OpenStack 的 oslo.utils 封装了 __import__,支持动态导入 class, object 等。

 
import sys
import traceback

def import_class(import_str):
"""Returns a class from a string including module and class.
.. versionadded:: 0.3
"""
mod_str, _sep, class_str = import_str.rpartition('.')
__import__(mod_str)
try:
return getattr(sys.modules[mod_str], class_str)
except AttributeError:
raise ImportError('Class %s cannot be found (%s)' %
(class_str,
traceback.format_exception(*sys.exc_info())))

def import_object(import_str, *args, **kwargs):
"""Import a class and return an instance of it.
.. versionadded:: 0.3
"""
return import_class(import_str)(*args, **kwargs)

def import_module(import_str):
"""Import a module.
.. versionadded:: 0.3
"""
__import__(import_str)
return sys.modules[import_str]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import sys
import traceback
 
 
def import_class(import_str):
    """Returns a class from a string including module and class.
    .. versionadded:: 0.3
    """
    mod_str, _sep, class_str = import_str.rpartition('.')
    __import__(mod_str)
    try:
        return getattr(sys.modules[mod_str], class_str)
    except AttributeError:
        raise ImportError('Class %s cannot be found (%s)' %
                          (class_str,
                           traceback.format_exception(*sys.exc_info())))
 
 
def import_object(import_str, *args, **kwargs):
    """Import a class and return an instance of it.
    .. versionadded:: 0.3
    """
    return import_class(import_str)(*args, **kwargs)
 
 
def import_module(import_str):
    """Import a module.
    .. versionadded:: 0.3
    """
    __import__(import_str)
    return sys.modules[import_str]

__import__ 与动态加载 python module的更多相关文章

  1. Python_getattr+__import__ 实现动态加载模块、类对象或函数

    __import__() 语法 __import__(name[, globals[, locals[, fromlist[, level]]]]) 参数 name -- 字符串,模块的导入路径 说明 ...

  2. python基础-动态加载lazy_import(利用__import__)

    看了一天动态加载,普遍有这么几种方法,总结一下,由简入深,本文仅对查到的栗子们做个引用……省去你们大把查资料的时间= = 主要思想:把模块(文件)名.类名.方法名当成了变量 然后利用__import_ ...

  3. 转:从pickle看python类成员的动态加载和类的定位

      pickle是Python轻便的对象序列化工具.使用pickle可以方便地把python对象写入文件对象中,或者像soap那样在socket间传送.     按照python的一贯作风,类的成员在 ...

  4. python 动态加载类对象

    第一步 加载模块 module  =__import__("modulename",fromlist=['']) 第二部 加载类对象 cls = getattr(module, & ...

  5. python获取动态网站上面的动态加载的数据(初级)

    我们在处理一些网站数据的时候,有时候我们需要的数据很多都是动态加载的,而不都是静态的,以下以一个实例来介绍简单的获取动态数据,首先申明本人小白,还在学习python中,这个方法还是比较笨拙的,但是对于 ...

  6. Python+Selenium爬取动态加载页面(2)

    注: 上一篇<Python+Selenium爬取动态加载页面(1)>讲了基本地如何获取动态页面的数据,这里再讲一个稍微复杂一点的数据获取全国水雨情网.数据的获取过程跟人手动获取过程类似,所 ...

  7. Python+Selenium爬取动态加载页面(1)

    注: 最近有一小任务,需要收集水质和水雨信息,找了两个网站:国家地表水水质自动监测实时数据发布系统和全国水雨情网.由于这两个网站的数据都是动态加载出来的,所以我用了Selenium来完成我的数据获取. ...

  8. Python 动态加载并下载"梨视频"短视频

    下载链接:http://www.pearvideo.com/category_1 import requests from lxml import etree import re from urlli ...

  9. Python网络爬虫_爬取Ajax动态加载和翻页时url不变的网页

    1 . 什么是 AJAX ? AJAX = 异步 JavaScript 和 XML. AJAX 是一种用于创建快速动态网页的技术. 通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新 ...

随机推荐

  1. 支持向量机SVM进阶

    本文适合于对SVM基本概念有一点了解的童鞋. SVM基本概念: 最大边缘平面--基本原理:结构风险最小化 分类器的泛化误差 支持向量 问题描述: 请对一下数据,利用svm对其进行分类.       最 ...

  2. python框架---->pymysql的使用

    这里面学习一下python中操作mysql的第三方库pymysql的使用.很多我们以为一辈子都不会忘掉的事情,就在我们念念不忘的日子里.被我们遗忘了. pymysql的简单使用 我们创建一张表来进行下 ...

  3. Maven —— scope 元素的值及其含义

    1.compile 缺省值,所属依赖在所有的classpath中可用,同时它们也会被打包(随着项目一起发布). 2.provided 只有当JDK或者某个容器已提供该依赖之后才使用.如servlet. ...

  4. smarty assign变量赋值

    1.变量赋值的两种写法 <%assign var="name" value="cl"%> <%assign "name" ...

  5. laravel调用sql server存储过程并取得ReturnValue

    alter proc [dbo].[aaa](    @AgencyID int,--代理商ID    @AdminID int --结算操作人ID(管理员ID))asbegin    select ...

  6. Linux下应急工具

    Linux下的应急工具 在Linux下,应急的查看点无非那个几个,一是看表现(宕机.高CPU.高内存.高IO.高网络通信),二看连接.三看进程.四看日志.五看文件(Linux一切皆文件),再者结合起来 ...

  7. 【BZOJ1502】[NOI2005]月下柠檬树 Simpson积分

    [BZOJ1502][NOI2005]月下柠檬树 Description 李哲非常非常喜欢柠檬树,特别是在静静的夜晚,当天空中有一弯明月温柔地照亮地面上的景物时,他必会悠闲地坐在他亲手植下的那棵柠檬树 ...

  8. [工具] 将Sublime Text 3配置为C++代码编辑器

    { "path": "C:\\Dev-Cpp\\bin", "cmd": ["g++.exe", "${fil ...

  9. spring task的定时任务突然断了

    spring定时任务只开启一个线程去工作也就是串行工作,定时调度任务出现阻塞导致线程终止 加上这个试试 <!-- <task:annotation-driven /> --> ...

  10. thinkCMF----列表页跳转

    thinkCMF列表循环有个:用来循环文章列表. <php> $where=[ 'post.create_time'=>['egt',0] ]; $page=[ 'list_rows ...