imp访问-Superseded Modules(Python教程)(参考资料)
imp
– 访问 import internals
源代码: Lib / imp.py
自版本3.4以后不推荐使用: imp
包正在等待弃用importlib
.
这个模块提供了用于实现import
语句的机制的接口。它定义了以下常量和函数:
imp.
get_magic
()-
返回用于识别字节编译的代码文件的魔术字符串值(
.pyc
文件)。(对于每个Python版本,此值可能不同。)自版本3.4以后不推荐使用:使用
importlib.util.MAGIC_NUMBER
而不是
imp.
get_suffixes
()- 返回一个3元素元组的列表,每个元素描述一个特定类型的模块。每个三元组的形式为
(suffix, mode, type)
,其中suffix是要附加到模块名称的字符串,以形成要搜索的文件名,mode是传递给内置的模式字符串-inopen()
function打开文件(对于文本文件可以是"r"
,对于二进制文件可以是"rb"
),而type是文件类型,有其中一个值PY_SOURCE
,PY_COMPILED
,或C_EXTENSION
,描述如下自版本3.3以后删除:使用
importlib.machinery
上定义的常量代替
imp.
find_module
// (name [, path] )- 试着找到模块name。如果省略path或
None
,则会搜索sys.path
给出的目录名列表,但首先搜索几个特殊位置:该函数尝试查找内置模块使用thegiven名称(C_BUILTIN
),然后是一个冻结的模块(PY_FROZEN
),并且在某些系统上也会查看其他一些地方(在Windows上,它在注册表中看起来可能指向特定文件).否则,path必须是目录名列表;每个目录都会搜索上面
get_suffixes()
返回的任何后缀的文件。列表中的无效名称被静默忽略(但所有列表项都必须是字符串).如果搜索成功,返回值是一个3元素的元组
(file,pathname, description)
:file是一个开放的文件对象位于开头,pathname是找到的文件的路径名,description是
get_suffixes()
描述发现的那种模块.如果模块没有存放在文件中,则返回file是
None
,pathname是空字符串,description元组包含后缀和模式的emptystrings;模块类型表示为上面给出的内容。如果搜索不成功,ImportError
israised。其他例外表明问题orenvironment.如果模块是一个包,file是
None
, pathname是包路径和description中的最后一项元组是PKG_DIRECTORY
.此函数不处理分层模块名称(包含点的名称)。为了找到P.M,即包M的子模块P,使用
find_module()
和load_module()
查找并加载包P然后使用find_module()
并将path参数设置为P.__path__
。当P本身有一个虚线名称时,递归应用此配方.自版本3.3以后不推荐使用:使用
importlib.util.find_spec()
相反,除非需要Python 3.3兼容性,在这种情况下使用importlib.find_loader()
。例如使用前一种情况,请参阅例子的一部分importlib
documentation.
imp.
load_module
(name, file, pathname, description)- 加载之前由
find_module()
(或通过另一种进行的搜索产生兼容的结果)。此功能不仅仅是导入模块:如果模块已经导入,它将重新加载模块!nameargument表示fullmodule名称(包括包名称,如果这是apackage的子模块)。file参数是一个打开的文件,pathname是相应的文件名;这些可以是None
和""
,分别是模块是包还是没有从文件加载。description参数是一个元组,由get_suffixes()
返回,描述了必须加载的模块类型.如果加载成功,则返回值为模块对象;否则,例外(通常是
ImportError
)被抬起来重要:调用者负责关闭file参数,如果不是
None
,即使引发异常也是如此。最好用try
…finally
陈述自版本3.3以后删除:如果以前和
imp.find_module()
一起使用那么考虑使用importlib.import_module()
,否则请使用您为imp.find_module()
选择的替换装置。如果你直接用文件路径参数调用imp.load_module()
和相关函数,那么使用importlib.util.spec_from_file_location()
和importlib.util.module_from_spec()
的组合。有关各种方法的详细信息,请参阅文件示例importlib
文件.
imp.
new_module
(name)- 返回一个名为name的新空模块对象。这个对象是not插入
sys.modules
.自版本3.4以后不推荐使用使用
importlib.util.module_from_spec()
代替
imp.
reload
(module)- 重新装入以前进口的module。参数必须是模块对象,之前必须已成功导入。如果您使用外部编辑器编写模块源文件并希望在不离开Python解释器的情况下尝试新版本,这将非常有用。返回值是模块对象(与module参数相同).
执行
reload(module)
时:- 重新编译Python模块的代码并且重新执行模块级代码,定义一组新的对象,这些对象绑定到模块的字典中的名称。扩展模块的
init
功能不被称为secondtime. - 与Python中的所有其他对象一样,只有在引用计数降到零之后才会回收旧对象.
- 模块命名空间中的名称被更新为指向任何new或changedobjects.
- 其他对旧对象的引用(例如模块外部的名称)不会被反弹以引用新对象,并且必须在每个对象中更新如果需要,它们会出现在命名空间.
还有其他一些注意事项:
重新加载模块时,会保留其字典(包含模块的全局变量)。名称的重新定义将覆盖旧的定义,因此这通常不是问题。如果模块化的新版本未定义旧版本定义的名称,则旧定义将保留。如果它保持全局表或对象缓存,则此功能可用于模块的优势 – 使用
try
语句可以测试表的存在并在需要时跳过其初始化:try: cache except NameError: cache = {}
这是合法的虽然通常对重新加载内置或动态加载的模块没有多大用处,但
sys
,__main__
和builtins
除外。但是,在很多情况下,扩展模块的设计不是多次初始化,可能会失败重新加载时以任意方式如果模块使用
from
…import
…从另一个模块导入对象,则调用reload()
对于另一个模块没有重新定义从它导入的对象 – 一种方法是重新执行from
语句,另一种方法是使用import
和qualifiednames(module.*name *)而不是如果一个模块实例化一个类的实例,重新加载定义该类的模块不会影响实例的方法定义 – 它们继续使用旧的类定义。对于派生类也是如此.
在版本3.3中更改:依赖于
__name__
和__loader__
在模块重新加载时定义而不是仅仅__name__
.自版本3.4以后不推荐使用:使用
importlib.reload()
代替 - 重新编译Python模块的代码并且重新执行模块级代码,定义一组新的对象,这些对象绑定到模块的字典中的名称。扩展模块的
以下功能便于处理 PEP 3147 byte-compiledfile paths.
新版本3.2.
imp.
cache_from_source
(path, debug_override=None)- 返回 PEP 3147 与源path关联的字节编译文件的路径。例如,如果path是
/foo/bar/baz.py
,对于Python 3.2,返回值将是/foo/bar/__pycache__/baz.cpython-32.pyc
。cpython-32
字符串来自当前的魔术标签(见get_tag()
;如果sys.implementation.cache_tag
没有定义然后NotImplementedError
将被提出)。通过True
或False
传入debug_override你可以覆盖__debug__
的系统值,导致优化的字节码.path不需要存在。
改版3.3:如果
sys.implementation.cache_tag
是None
, 然后NotImplementedError
被养了从版本3.4开始不推荐使用:使用
importlib.util.cache_from_source()
代替。在版本3.5中更改:debug_override参数不再创建
.pyo
文件。
imp.
source_from_cache
(path)- 鉴于 path到PEP 3147 文件名,返回关联的源代码文件路径。例如,如果path是
/foo/bar/__pycache__/baz.cpython-32.pyc
返回的路径是/foo/bar/baz.py
. path不存在,但如果不符合PEP 3147 格式,ValueError
被提出来了。如果sys.implementation.cache_tag
没有定义,NotImplementedError
被养了改版3.3:举起
NotImplementedError
什么时候sys.implementation.cache_tag
没有定义。从版本3.4开始不推荐使用:使用
importlib.util.source_from_cache()
代替。
imp.
get_tag
()- 退回PEP 3147 魔法标记字符串匹配此版本的Python’smagic数字,由
get_magic()
.返回自版本3.4以后不推荐使用:使用
sys.implementation.cache_tag
直接从Python 3.3.
开始以下函数有助于与导入系统的内部锁定机制进行交互。锁定语义的导入是一个实现细节,可能因发行版本而异。但是,Python确保循环导入工作没有任何死锁.
imp.
lock_held
()- 如果全局导入锁当前被保持,则返回
True
,否则False
。在没有线程的平台上,总是返回False
.在具有线程的平台上,执行导入的线程首先持有全局导入锁,然后为导入的其余部分设置每模块锁。这会阻止其他线程导入相同的模块,直到原始导入完成,从而阻止其他线程看到原始线程构造的不完整的模块对象。对于循环导入有一个例外,通过构造必须在某些时候暴露出一个不完整的模块对象.
在版本3.3中更改:锁定方案已经改为大多数部分的模块锁。对于某些关键任务保留全局导入锁定,例如初始化每个模块的锁定.
自版本3.4以后重新编写.
imp.
acquire_lock
()- 获取当前线程的解释器全局导入锁。导入挂钩应使用此锁,以确保在导入模块时的线程安全性.
一旦线程获得了导入锁定,同一个线程就可以在不阻塞的情况下获取它;线程必须在每次获取它时才释放一次.
在没有线程的平台上,这个功能什么都不做.
在版本3.3中更改:锁定方案有在大多数情况下改为按模块锁定。对于某些关键任务保留全局导入锁定,例如初始化每个模块的锁定.
自版本3.4以后重新编写.
imp.
release_lock
()- 释放解释器的全局导入锁定。在没有线程的平台上,这个函数什么都不做.
在版本3.3中更改:锁定方案已经改为大多数部分的每个模块锁。对于某些关键任务保留全局导入锁定,例如初始化每个模块的锁定.
自版本3.4以后重新编写.
以下本模块中定义的具有整数值的常量是用于表示find_module()
.
imp.
PY_SOURCE
- 的搜索结果该模块被发现为源文件.
自版本3.3以后已弃用.
imp.
PY_COMPILED
- 该模块被发现是一个编译的代码对象文件.
自版本3.3以后已弃用.
imp.
C_EXTENSION
- 该模块被发现是可动态加载的共享库.
自版本3.3以后已弃用.
imp.
PKG_DIRECTORY
- 该模块被发现为软件包目录.
自版本3.3以后更改.
imp.
C_BUILTIN
- 该模块被发现为内置模块.
自版本3.3以后弃用
imp.
PY_FROZEN
- 该模块被发现是一个冷冻模块.
自版本3.3以后改为.
- class
imp.
NullImporter
(path_string) NullImporter
类型是一个 PEP 302 导入钩子,由于未能找到任何模块而处理非目录路径字符串。使用现有目录或空字符串调用此类型会引发ImportError
。否则,将返回NullImporter
实例.实例只有一种方法:
find_module
(fullname[, path] )- 这个方法总是返回
None
,表示找不到所要求的模块.
改版3.3:
None
被插入sys.path_importer_cache
而不是NullImporter
.从版本3.4开始不推荐使用:插入
None
进sys.path_importer_cache
代替。
例子
以下函数模拟了到1.4的标准导入语句(没有分层模块名称)。(这implementation在那个版本中不起作用,因为find_module()
已经延长了load_module()
已添加1.4。)
import imp
import sys
def __import__(name, globals=None, locals=None, fromlist=None):
# Fast path: see if the module has already been imported.
try:
return sys.modules[name]
except KeyError:
pass
# If any of the following calls raises an exception,
# there's a problem we can't handle -- let the caller handle it.
fp, pathname, description = imp.find_module(name)
try:
return imp.load_module(name, fp, pathname, description)
finally:
# Since we may exit via an exception, close fp explicitly.
if fp:
fp.close()