On this page
imp —访问导入内部
源代码: Lib/imp.py
自版本 3.4 起不推荐使用:不推荐使用imp模块,而推荐使用importlib。
该模块提供了用于实现import语句的机制的接口。它定义了以下常量和函数:
imp.
get_magic
( )- 返回用于识别字节编译的代码文件(
.pyc
个文件)的魔术字符串值。 (每个 Python 版本的此值可能不同.)
- 返回用于识别字节编译的代码文件(
从 3.4 版开始不推荐使用:改为使用importlib.util.MAGIC_NUMBER。
imp.
get_suffixes
( )- 返回一个三元素 Tuples 的列表,每个 Tuples 描述一种特定类型的模块。每个三 Tuples 的格式均为
(suffix, mode, type)
,其中* suffix 是要添加到模块名称后的字符串,以形成要搜索的文件名, mode 是要传递给内置open()函数以打开文件的模式字符串(对于文本文件,它可以是'r'
;对于二进制文件,它可以是'rb'
),而 type *是文件类型,其值如下所述PY_SOURCE,PY_COMPILED或C_EXTENSION之一。
- 返回一个三元素 Tuples 的列表,每个 Tuples 描述一种特定类型的模块。每个三 Tuples 的格式均为
从版本 3.3 开始不推荐使用:而是使用在importlib.machinery上定义的常量。
imp.
find_module
(* name * [,* path *])
否则,* path *必须是目录名称的列表;否则,在每个目录中搜索带有上面get_suffixes()返回的任何后缀的文件。列表中的无效名称将被静默忽略(但所有列表项必须为字符串)。
如果搜索成功,则返回值为 3 元素 Tuples(file, pathname, description)
:
- file 是一个位于开头的开放file object, pathname 是找到的文件的路径名, description *是一个 3 元素 Tuples,包含在get_suffixes()返回的列表中,描述了找到的模块的类型。
如果模块是内置的或冻结的,则* file 和 pathname 均为None
,并且 description *Tuples 的后缀和模式包含空字符串;模块类型如上括号中所示。如果搜索失败,则引发ImportError。其他异常表明参数或环境存在问题。
如果模块是包,则* file 是None
, pathname 是包路径,并且 description *Tuples 中的最后一项是PKG_DIRECTORY。
此函数不处理分层模块名称(包含点的名称)。为了找到* P.M ,即包 P 的子模块 M ,请使用find_module()和load_module()查找并加载包 P ,然后将find_module()的 path 参数设置为P.__path__
。当 P *本身具有点名时,请递归应用此配方。
从版本 3.3 开始不推荐使用:除非需要 Python 3.3 兼容性,否则请使用importlib.util.find_spec(),在这种情况下请使用importlib.find_loader()。有关前一种情况的用法示例,请参见importlib文档的Examples部分。
imp.
load_module
(* name , file , pathname , description *)- 加载先前由find_module()找到的模块(或pass其他进行的搜索产生兼容的结果)。该Function不仅仅可以导入模块:如果模块已经被导入,它将重新加载模块! * name *参数指示完整的模块名称(包括软件包名称,如果这是软件包的子模块)。 * file 参数是一个打开的文件, pathname *是相应的文件名;当模块是软件包或未从文件加载时,它们分别可以是
None
和''
。 * description *参数是一个 Tuples,由get_suffixes()返回,描述了必须加载哪种模块。
- 加载先前由find_module()找到的模块(或pass其他进行的搜索产生兼容的结果)。该Function不仅仅可以导入模块:如果模块已经被导入,它将重新加载模块! * name *参数指示完整的模块名称(包括软件包名称,如果这是软件包的子模块)。 * file 参数是一个打开的文件, pathname *是相应的文件名;当模块是软件包或未从文件加载时,它们分别可以是
如果加载成功,则返回值为模块对象。否则,将引发异常(通常为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文档的Examples部分。
imp.
new_module
(* name *)- 返回一个名为* name *的新的空模块对象。 未将此对象插入
sys.modules
。
- 返回一个名为* name *的新的空模块对象。 未将此对象插入
从 3.4 版开始不推荐使用:改为使用importlib.util.module_from_spec()。
imp.
reload
(* module *)- 重新加载先前导入的* module 。参数必须是模块对象,因此它必须已经成功导入。如果您已使用外部编辑器编辑了模块源文件,并且想在不离开 Python 解释器的情况下try新版本,则这将非常有用。返回值是模块对象(与 module *参数相同)。
当执行reload(module)
时:
重新编译 Python 模块的代码并重新执行模块级代码,从而定义了一组新对象,这些对象绑定到模块字典中的名称。扩展模块的
init
Function不再被调用。与 Python 中的所有其他对象一样,旧对象仅在其引用计数降至零后才被回收。
模块名称空间中的名称将更新为指向任何新的或更改的对象。
对旧对象的其他引用(例如模块外部的名称)不会反弹以引用新对象,并且如果需要的话,必须在出现它们的每个命名空间中进行更新。
还有其他一些警告:
重新加载模块时,将保留其字典(包含模块的全局变量)。名称的重新定义将覆盖旧的定义,因此这通常不是问题。如果模块的新版本未定义旧版本定义的名称,则保留旧定义。如果此Function维护模块的全局表或对象缓存,则可以利用该模块的优势-使用try语句,它可以测试表的存在并在需要时跳过其初始化:
try:
cache
except NameError:
cache = {}
尽管sys,main和builtins除外,但重新加载内置或动态加载的模块通常不是很有用,但这是合法的。但是,在许多情况下,扩展模块的设计不会被初始化一次以上,并且在重新加载时可能会以任意方式失败。
如果一个模块使用from…import…从另一个模块导入对象,则对另一个模块调用reload()不会重新定义从其导入的对象-一种解决方法是重新执行from
语句,另一种方法是使用import
和限定名称(* module . name *)代替。
如果模块实例化一个类的实例,则重新加载定义该类的模块不会影响实例的方法定义-它们将 continue 使用旧的类定义。派生类也是如此。
在版本 3.3 中进行了更改:依赖于在重新加载的模块上定义的__name__
和__loader__
,而不仅仅是__name__
。
从 3.4 版开始不推荐使用:改为使用importlib.reload()。
以下Function为处理 PEP 3147个字节编译的文件路径提供了便利。
3.2 版中的新Function。
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)。pass为_debug_override *传递True
或False
,可以覆盖__debug__
的系统值,从而优化字节码。
- 将 PEP 3147路径返回到与源* path 关联的字节编译文件。例如,如果 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 *)- 给定 PEP 3147文件名的* path ,返回相关的源代码文件路径。例如,如果 path *是
/foo/bar/__pycache__/baz.cpython-32.pyc
,则返回的路径将是/foo/bar/baz.py
。 * path *不必存在,但是,如果它不符合 PEP 3147格式,则会引发ValueError。如果未定义sys.implementation.cache_tag
,则引发NotImplementedError。
- 给定 PEP 3147文件名的* path ,返回相关的源代码文件路径。例如,如果 path *是
在版本 3.3 中更改:未定义sys.implementation.cache_tag
时提高NotImplementedError。
从 3.4 版开始不推荐使用:改为使用importlib.util.source_from_cache()。
imp.
get_tag
( )- 返回get_magic()返回的 PEP 3147魔术标签字符串,该字符串与该版本的 Python 魔术数匹配。
从 3.4 版开始不推荐使用:从 python 3.3 开始直接使用sys.implementation.cache_tag
。
以下Function有助于与导入系统的内部锁定机制进行交互。导入的锁定语义是一个实现细节,每个发行版可能会有所不同。但是,Python 确保循环导入可以正常工作而不会出现任何死锁。
imp.
lock_held
( )- 如果当前持有全局导入锁,则返回
True
,否则返回False
。在没有线程的平台上,始终返回False
。
- 如果当前持有全局导入锁,则返回
在具有线程的平台上,执行导入的线程首先拥有全局导入锁,然后为其余的导入设置每个模块的锁。这将阻止其他线程导入同一模块,直到原始导入完成为止,从而防止其他线程看到由原始线程构造的不完整的模块对象。循环导入有一个 exception,循环导入必须pass构造在某个点公开不完整的模块对象。
在版本 3.3 中进行了更改:在大多数情况下,锁定方案已更改为按模块锁定。对于某些关键任务,将保留全局导入锁,例如初始化每个模块的锁。
自 3.4 版起不推荐使用。
imp.
acquire_lock
( )- 获取当前线程的解释器的全局导入锁。导入钩子应使用此锁,以确保导入模块时的线程安全。
一旦线程获取了导入锁,同一线程就可以再次获取它而不会阻塞;线程必须在每次获取它后释放一次。
在没有线程的平台上,此Function不执行任何操作。
在版本 3.3 中进行了更改:在大多数情况下,锁定方案已更改为按模块锁定。对于某些关键任务,将保留全局导入锁,例如初始化每个模块的锁。
自 3.4 版起不推荐使用。
imp.
release_lock
( )- 释放解释器的全局导入锁。在没有线程的平台上,此Function不执行任何操作。
在版本 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导入钩子,它pass找不到任何模块来处理非目录路径字符串。用现有目录或空字符串调用此类型会引发ImportError。否则,将返回一个NullImporter实例。
- class *
实例只有一种方法:
find_module
((全名 [,路径])- 此方法始终返回
None
,指示找不到请求的模块。
- 此方法始终返回
在版本 3.3 中进行了更改:None
而不是NullImporter的实例被插入sys.path_importer_cache
。
从 3.4 版开始不推荐使用:将None
插入sys.path_importer_cache
。
Examples
以下函数模拟 Python 1.4 之前的标准 import 语句(无分层模块名称)。 (此实现在该版本中不起作用,因为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()