__import__ 与动态加载 python module
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 加载,例如:
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__ 的用法如下:
|
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
>>> 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 的,比如:
最终调用如下函数实现
foo = __import__('foo', globals(), locals(), [], -1)
|
1
2
3
4
5
6
|
import foo
最终调用如下函数实现
foo = __import__('foo', globals(), locals(), [], -1)
|
但如果使用不善,也容易踩坑:
<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 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的更多相关文章
- Python_getattr+__import__ 实现动态加载模块、类对象或函数
__import__() 语法 __import__(name[, globals[, locals[, fromlist[, level]]]]) 参数 name -- 字符串,模块的导入路径 说明 ...
- python基础-动态加载lazy_import(利用__import__)
看了一天动态加载,普遍有这么几种方法,总结一下,由简入深,本文仅对查到的栗子们做个引用……省去你们大把查资料的时间= = 主要思想:把模块(文件)名.类名.方法名当成了变量 然后利用__import_ ...
- 转:从pickle看python类成员的动态加载和类的定位
pickle是Python轻便的对象序列化工具.使用pickle可以方便地把python对象写入文件对象中,或者像soap那样在socket间传送. 按照python的一贯作风,类的成员在 ...
- python 动态加载类对象
第一步 加载模块 module =__import__("modulename",fromlist=['']) 第二部 加载类对象 cls = getattr(module, & ...
- python获取动态网站上面的动态加载的数据(初级)
我们在处理一些网站数据的时候,有时候我们需要的数据很多都是动态加载的,而不都是静态的,以下以一个实例来介绍简单的获取动态数据,首先申明本人小白,还在学习python中,这个方法还是比较笨拙的,但是对于 ...
- Python+Selenium爬取动态加载页面(2)
注: 上一篇<Python+Selenium爬取动态加载页面(1)>讲了基本地如何获取动态页面的数据,这里再讲一个稍微复杂一点的数据获取全国水雨情网.数据的获取过程跟人手动获取过程类似,所 ...
- Python+Selenium爬取动态加载页面(1)
注: 最近有一小任务,需要收集水质和水雨信息,找了两个网站:国家地表水水质自动监测实时数据发布系统和全国水雨情网.由于这两个网站的数据都是动态加载出来的,所以我用了Selenium来完成我的数据获取. ...
- Python 动态加载并下载"梨视频"短视频
下载链接:http://www.pearvideo.com/category_1 import requests from lxml import etree import re from urlli ...
- Python网络爬虫_爬取Ajax动态加载和翻页时url不变的网页
1 . 什么是 AJAX ? AJAX = 异步 JavaScript 和 XML. AJAX 是一种用于创建快速动态网页的技术. 通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新 ...
随机推荐
- poj_1042 贪心算法
poj 1042 gone fishing 题目要求: 由有n个湖, 按照顺序排列,一个人从第一个湖向最后一个湖行进(方向只能从湖0到湖n-1),途中可以在湖中钓鱼.在每个湖中钓鱼时,开始的5分钟内可 ...
- 【python3】爬取新浪的栏目分类
目标地址: http://www.sina.com.cn/ 查看源代码,分析: 1 整个分类 在 div main-nav 里边包含 2 分组情况:1,4一组 . 2,3一组 . 5 一组 .6一组 ...
- MYSQL的索引和常见函数
MySQL的索引 索引机制 MySQL属于关系型数据库,为了提高查询速度,可以创建索引. 索引:由表中的一个或多个字段生成的键组成,这些键存储在数据结构(B树或者hash表中),于是又分为B树索引(I ...
- 【咸鱼教程】Egret中可长按复制的文本(例如复制优惠码)
一 实际效果二 实现原理三 源码下载 在egret中实现长按复制文本效果,一般用于复制优惠码什么的. 一 实际效果 二 实现原理 在egret的游戏元素都是绘制在canvas上的,我们 ...
- 【CF908E】New Year and Entity Enumeration 位运算+DP
[CF908E]New Year and Entity Enumeration 题意:给定$M=2^m-1$,我们称一个集合S是好的,当且仅当它满足:1.$\forall a\in S,a\ \ma ...
- 【Win】使用L2TP出现809错误
1.环境:win7/10 2.解决: a.修改注册表(新建一个文本文件,复制以下内容,保存后文件扩展名改为.reg,双击运行文件.) Windows Registry Editor Version 5 ...
- Solve minGW g++ has stopped working 程序停止运行
之前在机子装了个很早版本的MinGW,苦于不支持c++11,所以打算卸载掉安装个新版本的.可是网上找了很多版本装好后,编译成功,运行的时候总是弹出 *.exe has stopped working的 ...
- Asp.net MVC]Asp.net MVC5系列——在模型中添加
目录 概述 在模型中添加验证规则 自定义验证规则 伙伴类的使用 总结 系列文章 [Asp.net MVC]Asp.net MVC5系列——第一个项目 [Asp.net MVC]Asp.net MVC5 ...
- 执行环境可以在SQLPLUS.EXE或者DOS(命令行)中执行
Oracle数据导入导出imp/exp就相当于oracle数据还原与备份.exp命令可以把数据从远程数据库服务器导出到本地的dmp文件,imp命 令可以把dmp文件从本地导入到远处的数据库服务器中. ...
- Java中-classpath和路径的使用
javac -classpath的使用: javac:如果当前你要编译的java文件中引用了其它的类(比如说:继承),但该引用类的.class文件不在当前目录下,这种情况下就需要在javac命令后面加 ...