importlib
--- The implementation of import
¶
3.1 新版功能.
源代码: Lib/importlib/__init__.py
介绍¶
目的 importlib
包裹是两折的。一是提供 import
声明(因此,通过扩展, __import__()
函数)在python源代码中。这提供了 import
它可以移植到任何Python解释器。这也提供了一个比用编程语言而不是Python实现更容易理解的实现。
第二,要实现的组件 import
在此包中公开,使用户更容易创建自己的自定义对象(通常称为 importer )参与输入过程。
参见
- 这个 import 陈述
的语言引用
import
语句。- Packages specification
封装的原始规格。自编写本文档以来,一些语义发生了变化(例如,基于
None
在里面sys.modules
)- 这个
__import__()
功能 这个
import
语句是这个函数的句法糖。- PEP 235
在不区分大小写的平台上导入
- PEP 263
定义python源代码编码
- PEP 302
新导入挂钩
- PEP 328
导入:多行和绝对/相对
- PEP 366
主模块显式相对导入
- PEP 420
隐式命名空间包
- PEP 451
导入系统的modulespec类型
- PEP 488
消除PYO文件
- PEP 489
多相扩展模块初始化
- PEP 552
确定性Pycs
- PEP 3120
使用UTF-8作为默认源编码
- PEP 3147
PYC存储库目录
功能¶
- importlib.__import__(name, globals=None, locals=None, fromlist=(), level=0)¶
内置的实现
__import__()
功能。注解
模块的程序导入应使用
import_module()
而不是这个函数。
- importlib.import_module(name, package=None)¶
导入模块。这个 name 参数指定以绝对或相对术语(例如
pkg.mod
或..mod
)。如果名称是用相对术语指定的,则 包裹 参数必须设置为要用作解析包名称的定位点的包的名称(例如import_module('..mod', 'pkg.subpkg')
将输入pkg.mod
)这个
import_module()
函数充当一个简化的封装器importlib.__import__()
. 这意味着函数的所有语义都是从importlib.__import__()
. 这两个函数之间最重要的区别是import_module()
返回指定的包或模块(例如pkg.mod
)__import__()
返回顶级包或模块(例如pkg
)如果动态导入自解释器开始执行以来创建的模块(例如,创建了一个python源文件),则可能需要调用
invalidate_caches()
以便导入系统注意到新模块。在 3.3 版更改: 父包将自动导入。
- importlib.find_loader(name, path=None)¶
在指定的 path . 如果模块在
sys.modules
然后sys.modules[name].__loader__
返回(除非加载程序None
或未设置,在这种情况下ValueError
提高了)。否则,使用sys.meta_path
完成了。None
如果找不到加载程序,则返回。点式名称没有隐式导入其父项,因为这需要加载它们,可能不需要。要正确导入子模块,需要导入子模块的所有父包,并使用正确的参数 path .
3.3 新版功能.
在 3.4 版更改: 如果
__loader__
未设置,升高ValueError
,就像属性设置为None
.3.4 版后已移除: 使用
importlib.util.find_spec()
相反。
- importlib.invalidate_caches()¶
使存储在的查找器的内部缓存无效
sys.meta_path
. 如果查找器实现invalidate_caches()
然后调用它来执行失效。如果在程序运行时创建/安装了任何模块,则应调用此函数,以确保所有查找程序都会注意到新模块的存在。3.3 新版功能.
- importlib.reload(module)¶
重新加载以前导入的 模块 . 参数必须是一个模块对象,因此它以前必须成功导入。如果您已经使用外部编辑器编辑了模块源文件,并且希望在不离开Python解释器的情况下试用新版本,那么这将非常有用。返回值是模块对象(如果重新导入导致将不同的对象放入
sys.modules
)什么时候?
reload()
执行:python模块的代码被重新编译并重新执行模块级代码,通过重用 loader 最初加载模块。这个
init
扩展模块的函数没有第二次调用。与Python中的所有其他对象一样,旧对象只有在其引用计数降至零后才会被回收。
模块命名空间中的名称将更新为指向任何新对象或更改的对象。
对旧对象的其他引用(如模块外部的名称)不会反弹以引用新对象,如果需要,则必须在出现新对象的每个命名空间中进行更新。
还有许多其他注意事项:
当模块重新加载时,它的字典(包含模块的全局变量)将被保留。重新定义名称将覆盖旧的定义,因此这通常不是问题。如果模块的新版本未定义由旧版本定义的名称,则保留旧定义。如果模块维护对象的全局表或缓存,则可以利用此功能
try
语句,它可以测试表是否存在,如果需要,则跳过其初始化::try: cache except NameError: cache = {}
通常,重新加载内置或动态加载的模块并不十分有用。重装
sys
,__main__
,builtins
不建议使用其他关键模块。在许多情况下,扩展模块不能被设计为多次初始化,并且在重新加载时可能以任意方式失败。如果某个模块使用
from
…import
……调用reload()
因为另一个模块没有重新定义从它导入的对象——一种方法是重新执行from
声明,另一个是使用import
和限定名( module.name 相反。如果一个模块实例化一个类的实例,那么重新加载定义该类的模块不会影响实例的方法定义——它们继续使用旧的类定义。派生类也是如此。
3.4 新版功能.
在 3.7 版更改:
ModuleNotFoundError
当重新加载的模块缺少ModuleSpec
.
importlib.abc
--与导入相关的抽象基类¶
源代码: Lib/importlib/abc.py
这个 importlib.abc
模块包含 import
.还提供了核心抽象基类的一些子类来帮助实现核心ABC。
ABC层次结构:
object
+-- Finder (deprecated)
| +-- MetaPathFinder
| +-- PathEntryFinder
+-- Loader
+-- ResourceLoader --------+
+-- InspectLoader |
+-- ExecutionLoader --+
+-- FileLoader
+-- SourceLoader
- class importlib.abc.Finder¶
表示 finder .
3.3 版后已移除: 使用
MetaPathFinder
或PathEntryFinder
相反。- abstractmethod find_module(fullname, path=None)¶
用于查找 loader 对于指定的模块。最初在中指定 PEP 302 ,此方法用于
sys.meta_path
在基于路径的导入子系统中。在 3.4 版更改: 返回
None
当调用而不是引发时NotImplementedError
.
- class importlib.abc.MetaPathFinder¶
表示 meta path finder . 为了兼容性,这是
Finder
.3.3 新版功能.
- find_spec(fullname, path, target=None)¶
用于查找 spec 对于指定的模块。如果这是顶级导入, path 将
None
. 否则,这是对子包或模块的搜索,并且 path 将是的价值__path__
来自父包。如果找不到规格,None
返回。当通过时,target
是一个模块对象,finder可以使用它对返回的规范进行更合理的猜测。importlib.util.spec_from_loader()
可能有助于具体实施MetaPathFinders
.3.4 新版功能.
- find_module(fullname, path)¶
用于查找 loader 对于指定的模块。如果这是顶级导入, path 将
None
. 否则,这是对子包或模块的搜索,并且 path 将是的价值__path__
来自父包。如果找不到加载器,None
返回。如果
find_spec()
定义后,提供向后兼容的功能。在 3.4 版更改: 返回
None
当调用而不是引发时NotImplementedError
.可以使用find_spec()
提供功能。3.4 版后已移除: 使用
find_spec()
相反。
- invalidate_caches()¶
一种可选方法,调用时应使查找程序使用的任何内部缓存失效。被使用
importlib.invalidate_caches()
当对上的所有查找器的缓存无效时sys.meta_path
.在 3.4 版更改: 返回
None
当调用而不是NotImplemented
.
- class importlib.abc.PathEntryFinder¶
表示 path entry finder . 尽管它与
MetaPathFinder
,PathEntryFinder
仅用于由提供的基于路径的导入子系统PathFinder
. 这个ABC是Finder
仅出于兼容性原因。3.3 新版功能.
- find_spec(fullname, target=None)¶
用于查找 spec 对于指定的模块。查找器将仅在 path entry 分配给它的。如果找不到规格,
None
返回。当通过时,target
是一个模块对象,finder可以使用它对返回的规范进行更合理的猜测。importlib.util.spec_from_loader()
可能有助于具体实施PathEntryFinders
.3.4 新版功能.
- find_loader(fullname)¶
用于查找 loader 对于指定的模块。返回的2元组
(loader, portion)
在哪里?portion
是一系列文件系统位置,这些位置构成了命名空间包的一部分。加载器可能None
当指定portion
表示文件系统位置对命名空间包的贡献。空列表可用于portion
表示加载程序不是命名空间包的一部分。如果loader
是None
和portion
是空列表,则找不到命名空间包的加载程序或位置(即找不到模块的任何内容)。如果
find_spec()
定义,然后提供向后兼容的功能。在 3.4 版更改: 返回
(None, [])
而不是提高NotImplementedError
.使用find_spec()
提供功能时。3.4 版后已移除: 使用
find_spec()
相反。
- find_module(fullname)¶
具体实施
Finder.find_module()
相当于self.find_loader(fullname)[0]
.3.4 版后已移除: 使用
find_spec()
相反。
- invalidate_caches()¶
一种可选方法,调用时应使查找程序使用的任何内部缓存失效。被使用
PathFinder.invalidate_caches()
使所有缓存查找程序的缓存无效时。
- class importlib.abc.Loader¶
的抽象基类 loader . 见 PEP 302 对于加载器的确切定义。
希望支持资源读取的加载程序应实现
get_resource_reader(fullname)
规定的方法importlib.abc.ResourceReader
.在 3.7 版更改: 介绍了选修课
get_resource_reader()
方法。- create_module(spec)¶
一种方法,在导入模块时返回要使用的模块对象。此方法可能返回
None
,表示应该执行默认的模块创建语义。3.4 新版功能.
在 3.5 版更改: 从python 3.6开始,当
exec_module()
定义。
- exec_module(module)¶
在导入或重新加载模块时,在自己的命名空间中执行模块的抽象方法。当
exec_module()
被调用。当这种方法存在时,create_module()
必须定义。3.4 新版功能.
在 3.6 版更改:
create_module()
还必须定义。
- load_module(fullname)¶
用于加载模块的遗留方法。如果无法加载模块,
ImportError
引发,否则返回加载的模块。如果请求的模块已存在于
sys.modules
,应该使用该模块并重新加载。否则,加载程序应创建一个新模块并将其插入sys.modules
在任何加载开始之前,防止从导入中递归。如果加载器插入模块而装载失败,加载器必须从sys.modules
;模块已在sys.modules
在加载程序开始执行之前,应单独执行(请参见importlib.util.module_for_loader()
)加载程序应该在模块上设置几个属性。(请注意,当重新加载模块时,其中一些属性可能会发生更改):
__name__
模块的名称。
__file__
存储模块数据的路径(不为内置模块设置)。
__cached__
存储模块编译版本的路径(属性不合适时不设置)。
__path__
指定包中搜索路径的字符串列表。模块上未设置此属性。
__package__
将模块作为子模块加载到的包的完全限定名称(或顶级模块的空字符串)。对于包裹,它与
__name__
。这个importlib.util.module_for_loader()
装饰者可以处理以下细节__package__
。
__loader__
用于加载模块的加载程序。这个
importlib.util.module_for_loader()
装饰师可以处理__package__
.
什么时候?
exec_module()
是可用的,然后提供向后兼容的功能。在 3.4 版更改: 提高
ImportError
当调用而不是NotImplementedError
. 提供的功能exec_module()
可用。3.4 版后已移除: 用于加载模块的推荐API是
exec_module()
(和create_module()
)加载程序应该实现它,而不是加载模块()。在执行exec_module()时,导入机制负责加载_module()的所有其他职责。
- module_repr(module)¶
一种遗留方法,在实现时,它以字符串的形式计算并返回给定模块的repr。模块类型的默认repr()将根据需要使用此方法的结果。
3.3 新版功能.
在 3.4 版更改: 使成为可选的而不是抽象方法。
3.4 版后已移除: 输入机器现在自动处理这个问题。
- class importlib.abc.ResourceReader¶
被TraversableReader取代
安 abstract base class 提供阅读能力 资源 .
从ABC的角度来看, 资源 是在包中传送的二进制项目。通常,这类似于一个数据文件,它位于
__init__.py
包的文件。这个类的目的是帮助抽象出对这些数据文件的访问,这样无论包及其数据文件是否存储在例如zip文件中,还是存储在文件系统中。对于此类的任何方法,都是 资源 参数应为 path-like object 它在概念上只表示一个文件名。这意味着在 资源 参数。这是因为读卡器所在的包的位置充当“目录”。因此,目录和文件名的隐喻分别是包和资源。这也是这个类的实例应该直接关联到特定包(而不是潜在地表示多个包或一个模块)的原因。
希望支持资源读取的加载程序应提供一个名为
get_resource_reader(fullname)
它返回一个实现ABC接口的对象。如果由fullname指定的模块不是包,则此方法应返回None
. 只有当指定的模块是包时,才应返回与此ABC兼容的对象。3.7 新版功能.
- abstractmethod open_resource(resource)¶
返回打开的, file-like object 用于二进制读取 资源 .
如果找不到资源,
FileNotFoundError
提高了。
- abstractmethod resource_path(resource)¶
将文件系统路径返回到 资源 .
如果文件系统上不具体存在该资源,则引发
FileNotFoundError
.
- abstractmethod is_resource(name)¶
返回
True
如果命名 name 被视为资源。FileNotFoundError
如果 name 不存在。
- abstractmethod contents()¶
返回一个 iterable 包内容上的字符串。请注意,不要求迭代器返回的所有名称都是实际资源,例如,可以接受为其返回名称
is_resource()
是假的。允许返回非资源名称是为了允许预先知道如何存储包及其资源,并且非资源名称将很有用的情况。例如,允许返回子目录名,这样当知道包和资源存储在文件系统上时,就可以直接使用这些子目录名。
抽象方法返回无项的iterable。
- class importlib.abc.ResourceLoader¶
的抽象基类 loader 它实现了可选的 PEP 302 从存储后端加载任意资源的协议。
3.7 版后已移除: 该ABC被否决,赞成支持通过
importlib.abc.ResourceReader
.
- class importlib.abc.InspectLoader¶
的抽象基类 loader 它实现了可选的 PEP 302 用于检查模块的加载程序的协议。
- get_code(fullname)¶
返回模块的代码对象,或者
None
如果模块没有代码对象(例如,对于内置模块也是如此)。养一个ImportError
如果加载器找不到请求的模块。注解
虽然该方法有一个默认实现,但建议在可能的情况下对其进行重写以提高性能。
在 3.4 版更改: 不再是抽象的,并且提供了具体的实现。
- abstractmethod get_source(fullname)¶
返回模块源的抽象方法。它作为文本字符串返回,使用 universal newlines ,将所有识别的行分隔符转换为
'\n'
字符。返回None
如果没有可用的源(例如内置模块)。引发ImportError
如果加载程序找不到指定的模块。在 3.4 版更改: 引发
ImportError
而不是NotImplementedError
.
- is_package(fullname)¶
如果模块是包,则返回真值的抽象方法,否则返回假值。
ImportError
如果 loader 找不到模块。在 3.4 版更改: 引发
ImportError
而不是NotImplementedError
.
- static source_to_code(data, path='<string>')¶
从python源创建一个代码对象。
这个 data 参数可以是任何
compile()
函数支持(即字符串或字节)。这个 path 参数应该是源代码来源的“路径”,它可以是一个抽象概念(例如,zip文件中的位置)。使用随后的代码对象,可以通过运行
exec(code, module.__dict__)
.3.4 新版功能.
在 3.5 版更改: 使方法静态化。
- exec_module(module)¶
执行
Loader.exec_module()
.3.4 新版功能.
- load_module(fullname)¶
执行
Loader.load_module()
.3.4 版后已移除: 使用
exec_module()
相反。
- class importlib.abc.ExecutionLoader¶
继承自的抽象基类
InspectLoader
在实现时,这有助于将模块作为脚本执行。ABC表示可选 PEP 302 协议。- abstractmethod get_filename(fullname)¶
一种抽象方法,用于返回
__file__
对于指定的模块。如果没有可用的路径,ImportError
提高了。如果源代码可用,那么无论是否使用字节码加载模块,该方法都应返回源文件的路径。
在 3.4 版更改: 引发
ImportError
而不是NotImplementedError
.
- class importlib.abc.FileLoader(fullname, path)¶
继承自的抽象基类
ResourceLoader
和ExecutionLoader
,提供ResourceLoader.get_data()
和ExecutionLoader.get_filename()
.这个 全名 参数是加载程序要处理的模块的完全解析名称。这个 path 参数是模块的文件路径。
3.3 新版功能.
- name¶
加载程序可以处理的模块的名称。
- path¶
模块文件的路径。
- load_module(fullname)¶
调用超级
load_module()
.3.4 版后已移除: 使用
Loader.exec_module()
相反。
- abstractmethod get_data(path)¶
读数 path 作为一个二进制文件并返回其中的字节。
- class importlib.abc.SourceLoader¶
用于实现源(和可选的字节码)文件加载的抽象基类。类从两者继承
ResourceLoader
和ExecutionLoader
,要求执行:ExecutionLoader.get_filename()
只应返回源文件的路径;不支持无源加载。
此类定义的抽象方法用于添加可选的字节码文件支持。没有实现这些可选方法(或导致它们
NotImplementedError
)使加载程序只使用源代码。实现这些方法允许加载程序使用源 and 字节码文件;它不允许 无细胞的 仅提供字节码的加载。字节码文件是一种通过删除Python编译器的解析步骤来加快加载速度的优化,因此不会公开特定于字节码的API。- path_stats(path)¶
可选的抽象方法,返回
dict
包含指定路径的元数据。支持的字典键包括:'mtime'
(必选):表示源代码修改时间的整数或浮点数;'size'
(可选):源代码的字节大小。
字典中的任何其他键都将被忽略,以便将来扩展。如果无法处理路径,
OSError
提高了。3.3 新版功能.
在 3.4 版更改: 提高
OSError
而不是NotImplementedError
.
- path_mtime(path)¶
可选的抽象方法,返回指定路径的修改时间。
3.3 版后已移除: 此方法已被弃用,取而代之的是
path_stats()
. 您不必实现它,但它仍然可以用于兼容性目的。提高OSError
如果无法处理路径。在 3.4 版更改: 提高
OSError
而不是NotImplementedError
.
- set_data(path, data)¶
将指定字节写入文件路径的可选抽象方法。任何不存在的中间目录都将自动创建。
当写入路径失败时,因为该路径是只读的 (
errno.EACCES
/PermissionError
) ,不要传播异常。在 3.4 版更改: 不再引发
NotImplementedError
当被召唤时。
- get_code(fullname)¶
具体实施
InspectLoader.get_code()
.
- exec_module(module)¶
具体实施
Loader.exec_module()
.3.4 新版功能.
- load_module(fullname)¶
具体实施
Loader.load_module()
.3.4 版后已移除: 使用
exec_module()
相反。
- get_source(fullname)¶
具体实施
InspectLoader.get_source()
.
- is_package(fullname)¶
具体实施
InspectLoader.is_package()
. 如果模块的文件路径(如ExecutionLoader.get_filename()
)文件名为__init__
删除文件扩展名时 and 模块名称本身不以__init__
.
- class importlib.abc.Traversable¶
具有路径库路径适合遍历目录和打开文件的方法。
3.9 新版功能.
- class importlib.abc.TraversableReader¶
资源读取器的抽象基类,能够为
files
接口。子类ResourceReader并提供ResourceReader抽象方法的具体实现。因此,任何提供TraversableReader的加载器也提供ResourceReader。希望支持资源读取的加载程序应实现此接口。
3.9 新版功能.
importlib.resources
--资源¶
源代码: Lib/importlib/resources.py
3.7 新版功能.
该模块利用python的导入系统提供对 资源 在内部 封装 . 如果可以导入包,则可以访问该包中的资源。可以以二进制或文本模式打开或读取资源。
资源大致类似于目录中的文件,不过要记住这只是一个比喻,这一点很重要。资源和包 不 必须作为物理文件和目录存在于文件系统中。
注解
此模块提供的功能与 pkg_resources Basic Resource Access 没有该包的性能开销。这使得包中包含的读取资源更容易,语义更稳定和一致。
此模块的独立后端口提供了有关 using importlib.resources 和 migrating from pkg_resources to importlib.resources .
希望支持资源读取的加载程序应实现 get_resource_reader(fullname)
规定的方法 importlib.abc.ResourceReader
.
定义了以下类型。
- importlib.resources.Package¶
这个
Package
类型定义为Union[str, ModuleType]
. 这意味着函数描述接受Package
,可以传入字符串或模块。模块对象必须具有可解析的__spec__.submodule_search_locations
那不是None
.
- importlib.resources.Resource¶
此类型描述传递到此包中的各种函数的资源名称。定义如下:
Union[str, os.PathLike]
.
以下功能可用。
- importlib.resources.files(package)¶
返回一个
importlib.resources.abc.Traversable
对象,表示包(think目录)及其资源(think文件)的资源容器。可遍历的可以包含其他容器(考虑子目录)。包裹 是符合
Package
要求。3.9 新版功能.
- importlib.resources.open_binary(package, resource)¶
打开以进行二进制读取 资源 在内部 包裹 .
包裹 是符合
Package
要求。 资源 是要在其中打开的资源的名称 包裹 ;它可能不包含路径分隔符,也可能没有子资源(即它不能是目录)。此函数返回typing.BinaryIO
例如,一个二进制I/O流打开进行读取。
- importlib.resources.open_text(package, resource, encoding='utf-8', errors='strict')¶
打开以阅读文本 资源 在内部 包裹 . 默认情况下,资源以utf-8的形式打开进行读取。
包裹 是符合
Package
要求。 资源 是要在其中打开的资源的名称 包裹 ;它可能不包含路径分隔符,也可能没有子资源(即它不能是目录)。 encoding 和 errors 与内置的含义相同open()
.此函数返回
typing.TextIO
例如,一个打开供读取的文本I/O流。
- importlib.resources.read_binary(package, resource)¶
读取并返回 资源 在内部 包裹 作为
bytes
.包裹 是符合
Package
要求。 资源 是要在其中打开的资源的名称 包裹 ;它可能不包含路径分隔符,也可能没有子资源(即它不能是目录)。此函数将资源的内容返回为bytes
.
- importlib.resources.read_text(package, resource, encoding='utf-8', errors='strict')¶
阅读并返回 资源 在内部 包裹 作为一个
str
. 默认情况下,内容读取为严格的UTF-8。包裹 是符合
Package
要求。 资源 是要在其中打开的资源的名称 包裹 ;它可能不包含路径分隔符,也可能没有子资源(即它不能是目录)。 encoding 和 errors 与内置的含义相同open()
. 此函数将资源的内容返回为str
.
- importlib.resources.path(package, resource)¶
将路径返回到 资源 作为实际文件系统路径。此函数返回用于
with
语句。上下文管理器提供pathlib.Path
对象。退出上下文管理器将清除需要从zip文件等资源提取时创建的任何临时文件。
包裹 是符合
Package
要求。 资源 是要在其中打开的资源的名称 包裹 ;它可能不包含路径分隔符,也可能没有子资源(即它不能是目录)。
- importlib.resources.is_resource(package, name)¶
返回
True
如果存在名为的资源 name 在封装中,否则False
. 记住目录是 not 资源! 包裹 是符合Package
要求。
importlib.machinery
--导入器和路径挂钩¶
源代码: Lib/importlib/machinery.py
此模块包含各种有助于 import
查找和加载模块。
- importlib.machinery.SOURCE_SUFFIXES¶
表示源模块可识别文件后缀的字符串列表。
3.3 新版功能.
- importlib.machinery.DEBUG_BYTECODE_SUFFIXES¶
表示非优化字节码模块的文件后缀的字符串列表。
3.3 新版功能.
3.5 版后已移除: 使用
BYTECODE_SUFFIXES
相反。
- importlib.machinery.OPTIMIZED_BYTECODE_SUFFIXES¶
表示优化字节码模块的文件后缀的字符串列表。
3.3 新版功能.
3.5 版后已移除: 使用
BYTECODE_SUFFIXES
相反。
- importlib.machinery.BYTECODE_SUFFIXES¶
表示字节码模块(包括前导点)的可识别文件后缀的字符串列表。
3.3 新版功能.
在 3.5 版更改: 该值不再依赖于
__debug__
.
- importlib.machinery.EXTENSION_SUFFIXES¶
表示扩展模块可识别文件后缀的字符串列表。
3.3 新版功能.
- importlib.machinery.all_suffixes()¶
返回表示标准导入机制识别的模块的所有文件后缀的字符串组合列表。这是一个代码帮助器,它只需要知道文件系统路径是否潜在地引用了一个模块,而不需要任何关于模块类型的详细信息(例如,
inspect.getmodulename()
)3.3 新版功能.
- class importlib.machinery.BuiltinImporter¶
安 importer 对于内置模块。所有已知的内置模块都列在
sys.builtin_module_names
. 此类实现importlib.abc.MetaPathFinder
和importlib.abc.InspectLoader
ABC。这个类只定义了类方法,以减轻实例化的需要。
在 3.5 版更改: 作为一部分 PEP 489 ,内置导入程序现在实现
Loader.create_module()
和Loader.exec_module()
- class importlib.machinery.FrozenImporter¶
安 importer 对于冻结的模块。此类实现
importlib.abc.MetaPathFinder
和importlib.abc.InspectLoader
ABC。这个类只定义了类方法,以减轻实例化的需要。
在 3.4 版更改: 获得
create_module()
和exec_module()
方法。
- class importlib.machinery.WindowsRegistryFinder¶
Finder 用于在Windows注册表中声明的模块。此类实现
importlib.abc.MetaPathFinder
美国广播公司这个类只定义了类方法,以减轻实例化的需要。
3.3 新版功能.
3.6 版后已移除: 使用
site
而是配置。默认情况下,未来版本的python可能不会启用此finder。
- class importlib.machinery.PathFinder¶
A Finder 对于
sys.path
包装__path__
属性。此类实现importlib.abc.MetaPathFinder
美国广播公司这个类只定义了类方法,以减轻实例化的需要。
- classmethod find_spec(fullname, path=None, target=None)¶
尝试查找 spec 对于由指定的模块 全名 在
sys.path
或者,如果定义了,打开 path . 对于搜索的每个路径条目,sys.path_importer_cache
检查。如果找到非假对象,则将其用作 path entry finder 查找正在搜索的模块。如果在sys.path_importer_cache
然后sys.path_hooks
搜索路径条目的查找器,如果找到,则存储在sys.path_importer_cache
以及有关模块的查询。如果找不到任何人,那么None
都存储在缓存中并返回。3.4 新版功能.
在 3.5 版更改: 如果当前工作目录(由空字符串表示)不再有效,则
None
返回但未缓存任何值sys.path_importer_cache
.
- classmethod find_module(fullname, path=None)¶
传统封装
find_spec()
.3.4 版后已移除: 使用
find_spec()
相反。
- classmethod invalidate_caches()¶
调用
importlib.abc.PathEntryFinder.invalidate_caches()
在存储的所有查找器上sys.path_importer_cache
定义了方法。否则输入sys.path_importer_cache
设置为None
被删除。在 3.7 版更改: 条目
None
在里面sys.path_importer_cache
被删除。
在 3.4 版更改: 在中调用对象
sys.path_hooks
的当前工作目录''
(即空字符串)。
- class importlib.machinery.FileFinder(path, *loader_details)¶
具体实施
importlib.abc.PathEntryFinder
哪个缓存来自文件系统的结果。这个 path 参数是finder负责搜索的目录。
这个 loader_details 参数是一个2项元组的变量,每个元组包含一个加载器和一个加载器识别的文件后缀序列。加载程序应该是可调用的,它接受模块名称和找到的文件路径的两个参数。
finder将根据需要缓存目录内容,对每个模块搜索进行stat调用,以验证缓存是否过期。由于缓存过时依赖于操作系统文件系统状态信息的粒度,因此存在一个潜在的竞争条件,即搜索模块、创建新文件,然后搜索新文件表示的模块。如果操作发生得足够快,能够适应stat调用的粒度,那么模块搜索将失败。为了防止这种情况发生,在动态创建模块时,请确保调用
importlib.invalidate_caches()
.3.3 新版功能.
- path¶
查找器将搜索的路径。
- invalidate_caches()¶
清除内部缓存。
- classmethod path_hook(*loader_details)¶
一个类方法,返回用于
sys.path_hooks
. 一个实例FileFinder
由闭包使用直接给闭包的path参数返回,并且 loader_details 间接地。如果闭包的参数不是现有目录,
ImportError
提高了。
- class importlib.machinery.SourceFileLoader(fullname, path)¶
具体实施
importlib.abc.SourceLoader
子类化importlib.abc.FileLoader
并提供其他方法的一些具体实现。3.3 新版功能.
- name¶
此加载程序将处理的模块的名称。
- path¶
源文件的路径。
- path_stats(path)¶
- set_data(path, data)¶
- load_module(name=None)¶
具体实施
importlib.abc.Loader.load_module()
其中指定要加载的模块的名称是可选的。3.6 版后已移除: 使用
importlib.abc.Loader.exec_module()
相反。
- class importlib.machinery.SourcelessFileLoader(fullname, path)¶
具体实施
importlib.abc.FileLoader
可以导入字节码文件(即不存在源代码文件)。请注意,直接使用字节码文件(因而不是源代码文件)会阻止所有Python实现或更改字节码格式的新版本使用模块。
3.3 新版功能.
- name¶
加载程序将处理的模块的名称。
- path¶
字节码文件的路径。
- get_source(fullname)¶
返回
None
因为当使用这个加载程序时,字节码文件没有源。
- load_module(name=None)¶
具体实施
importlib.abc.Loader.load_module()
其中指定要加载的模块的名称是可选的。3.6 版后已移除: 使用
importlib.abc.Loader.exec_module()
相反。
- class importlib.machinery.ExtensionFileLoader(fullname, path)¶
具体实施
importlib.abc.ExecutionLoader
对于扩展模块。这个 全名 参数指定加载程序要支持的模块的名称。这个 path 参数是扩展模块文件的路径。
3.3 新版功能.
- name¶
加载程序支持的模块的名称。
- path¶
扩展模块的路径。
- is_package(fullname)¶
返回
True
如果文件路径指向包的__init__
基于模块EXTENSION_SUFFIXES
.
- get_code(fullname)¶
返回
None
因为扩展模块缺少代码对象。
- get_source(fullname)¶
返回
None
因为扩展模块没有源代码。
- class importlib.machinery.ModuleSpec(name, loader, *, origin=None, loader_state=None, is_package=None)¶
模块的导入系统相关状态的规范。这通常作为模块的
__spec__
属性。在下面的描述中,括号中的名称给出了直接在模块对象上可用的相应属性。例如。module.__spec__.origin == module.__file__
. 但是请注意,当 价值观 通常是等效的,因为这两个对象之间没有同步,所以它们可以不同。因此,可以更新模块的__path__
在运行时,这不会自动反映在__spec__.submodule_search_locations
.3.4 新版功能.
- name¶
(
__name__
)模块的完全限定名的字符串。
- loader¶
(
__loader__
)这个 Loader 加载模块时应使用的。 Finders 应该始终设置此设置。
- origin¶
(
__file__
)加载模块的位置的名称,例如内置模块的“built in”和从源加载模块的文件名。通常应设置“原点”,但可以
None
(默认值),表示未指定(例如,对于命名空间包)。- submodule_search_locations¶
(
__path__
)用于查找子模块的字符串列表(如果是包) (
None
否则)。- loader_state¶
装载期间使用的额外模块特定数据容器(或
None
)- cached¶
(
__cached__
)用于存储已编译模块的字符串(或
None
)- parent¶
(
__package__
)(只读)应将模块作为子模块加载到的包的完全限定名称(或顶级模块的空字符串)。对于包裹,它与
__name__
。- has_location¶
指示模块的“origin”属性是否引用可加载位置的布尔值。
importlib.util
--importers实用代码¶
此模块包含有助于构造 importer .
- importlib.util.MAGIC_NUMBER¶
表示字节码版本号的字节。如果需要加载/写入字节码的帮助,请考虑
importlib.abc.SourceLoader
.3.4 新版功能.
- importlib.util.cache_from_source(path, debug_override=None, *, optimization=None)¶
返回 PEP 3147/PEP 488 与源关联的字节编译文件的路径 path . 例如,如果 path 是
/foo/bar/baz.py
返回值为/foo/bar/__pycache__/baz.cpython-32.pyc
对于python 3.2。这个cpython-32
字符串来自当前的magic标记(请参见get_tag()
如果sys.implementation.cache_tag
则未定义NotImplementedError
将被引发)。这个 优化 参数用于指定字节码文件的优化级别。空字符串表示没有优化,因此
/foo/bar/baz.py
用一个 优化 属于''
将导致字节码路径/foo/bar/__pycache__/baz.cpython-32.pyc
.None
导致使用解释器的优化级别。使用任何其他值的字符串表示,因此/foo/bar/baz.py
用一个 优化 属于2
将导致的字节码路径/foo/bar/__pycache__/baz.cpython-32.opt-2.pyc
. 的字符串表示形式 优化 只能是字母数字,否则ValueError
提高了。这个 debug_override 参数已弃用,可用于重写系统的值
__debug__
. 一True
值等于设置值 optimization 到空字符串。一False
值与设置相同 optimization 到1
. 如果两者 debug_override 一个 optimization 不是None
然后TypeError
提高了。3.4 新版功能.
在 3.5 版更改: 这个 optimization 添加了参数,并且 debug_override 参数已弃用。
在 3.6 版更改: 接受一 path-like object .
- importlib.util.source_from_cache(path)¶
鉴于 path 到A PEP 3147 文件名,返回关联的源代码文件路径。例如,如果 path 是
/foo/bar/__pycache__/baz.cpython-32.pyc
返回的路径将是/foo/bar/baz.py
. path 但是,如果它不符合 PEP 3147 或 PEP 488 格式,AValueError
提高了。如果sys.implementation.cache_tag
未定义,NotImplementedError
提高了。3.4 新版功能.
在 3.6 版更改: 接受一 path-like object .
- importlib.util.decode_source(source_bytes)¶
解码表示源代码的给定字节,并将其作为带有通用换行符的字符串返回(根据
importlib.abc.InspectLoader.get_source()
)3.4 新版功能.
- importlib.util.resolve_name(name, package)¶
将相对模块名解析为绝对模块名。
如果 name 没有前导圆点,那么 name 只是简单地返回。这允许使用以下用途
importlib.util.resolve_name('sys', __spec__.parent)
而不进行检查以查看是否 套餐 需要论证。ImportError
如果 name 是相对模块名,但 包裹 是一个错误值(例如。None
或空字符串)。ImportError
也会引发一个相对名称,该相对名称将转义其包含的包(例如,请求..bacon
从内部spam
包装)。3.3 新版功能.
在 3.9 版更改: 要提高与import语句的一致性,请
ImportError
而不是ValueError
对于无效的相对导入尝试。
- importlib.util.find_spec(name, package=None)¶
找到 spec 对于模块,可以选择相对于指定的 包裹 姓名。如果模块在
sys.modules
然后sys.modules[name].__spec__
返回(除非规范None
或未设置,在这种情况下ValueError
提高了)。否则,使用sys.meta_path
完成了。None
如果找不到规范,则返回。如果 name 对于子模块(包含点),将自动导入父模块。
name 和 包裹 工作原理与
import_module()
.3.4 新版功能.
在 3.7 版更改: 引发
ModuleNotFoundError
而不是AttributeError
如果 包裹 实际上不是一个包裹(即缺少__path__
属性)。
- importlib.util.module_from_spec(spec)¶
基于创建新模块 spec 和
spec.loader.create_module
.如果
spec.loader.create_module
不返None
,则不会重置任何预先存在的属性。同样,没有AttributeError
如果在访问时触发,将引发 spec 或者在模块上设置属性。此功能优先于使用
types.ModuleType
将新模块创建为 spec 用于在模块上设置尽可能多的导入控制属性。3.5 新版功能.
- @importlib.util.module_for_loader¶
A decorator 对于
importlib.abc.Loader.load_module()
处理选择要加载的适当模块对象。修饰方法应该有一个调用签名,它采用两个位置参数(例如load_module(self, module)
)第二个参数是模块 object 供加载器使用。请注意,由于假设有两个参数,装饰器将不在静态方法上工作。装饰方法将采用 name 将按预期加载的模块的 loader . 如果在
sys.modules
然后建造一个新的。不管模块来自何处,__loader__
设置为 self 和__package__
是根据什么设置的importlib.abc.InspectLoader.is_package()
返回(如果可用)。这些属性被无条件地设置为支持重新加载。如果修饰方法引发异常并向添加模块
sys.modules
,然后移除模块,以防止部分初始化的模块留在sys.modules
. 如果模块已经在sys.modules
然后就让它一个人呆着。在 3.3 版更改:
__loader__
和__package__
自动设置(如果可能)。在 3.4 版更改: 集合
__name__
,__loader__
__package__
无条件支持重新加载。3.4 版后已移除: 导入机制现在直接执行此功能提供的所有功能。
- @importlib.util.set_loader¶
A decorator 对于
importlib.abc.Loader.load_module()
设置__loader__
返回模块的属性。如果属性已经设置,则装饰器不执行任何操作。假定封装方法的第一个位置参数(即self
是什么?__loader__
应设置为。在 3.4 版更改: 集合
__loader__
如果设置为None
,就好像属性不存在一样。3.4 版后已移除: 输入机器会自动处理这个问题。
- @importlib.util.set_package¶
A decorator 对于
importlib.abc.Loader.load_module()
设置__package__
返回模块的属性。如果__package__
已设置并且具有一个除None
不会改变。3.4 版后已移除: 输入机器会自动处理这个问题。
- importlib.util.spec_from_loader(name, loader, *, origin=None, is_package=None)¶
用于创建
ModuleSpec
基于加载程序的实例。这些参数与modulespec的含义相同。函数使用可用的 loader API,如InspectLoader.is_package()
,填写规范中缺少的信息。3.4 新版功能.
- importlib.util.spec_from_file_location(name, location, *, loader=None, submodule_search_locations=None)¶
用于创建
ModuleSpec
基于文件路径的实例。缺少的信息将通过使用加载器API和暗示模块将基于文件在规范中填写。3.4 新版功能.
在 3.6 版更改: 接受一 path-like object .
- importlib.util.source_hash(source_bytes)¶
返回的hash值 source_bytes 作为字节。基于hash的
.pyc
文件嵌入source_hash()
对应源文件头中的内容。3.7 新版功能.
- class importlib.util.LazyLoader(loader)¶
一个类,它将模块的装入程序的执行推迟到模块具有访问属性为止。
这个类 only 与定义
exec_module()
需要控制模块使用的模块类型。出于同样的原因,加载器的create_module()
方法必须返回None
或其类型__class__
属性可以随不使用而改变 slots . 最后,模块替换放置在sys.modules
无法正常工作,因为无法安全地替换整个解释器中的模块引用;ValueError
如果检测到此类替换,则引发。注解
对于启动时间至关重要的项目,此类允许在从不使用模块的情况下将加载模块的成本降至最低。对于启动时间不重要的项目,则使用此类 沉重地 由于在加载过程中创建的错误消息被延迟,因而出现在上下文之外,因此不鼓励使用。
3.5 新版功能.
在 3.6 版更改: 开始调用
create_module()
,正在删除的兼容性警告importlib.machinery.BuiltinImporter
和importlib.machinery.ExtensionFileLoader
.- classmethod factory(loader)¶
一个静态方法,它返回一个可调用的创建一个懒惰的加载程序。这是为了在加载程序由类而不是由实例传递的情况下使用。::
suffixes = importlib.machinery.SOURCE_SUFFIXES loader = importlib.machinery.SourceFileLoader lazy_loader = importlib.util.LazyLoader.factory(loader) finder = importlib.machinery.FileFinder(path, (lazy_loader, suffixes))
实例¶
以编程方式导入¶
要以编程方式导入模块,请使用 importlib.import_module()
. ::
import importlib
itertools = importlib.import_module('itertools')
检查模块是否可以导入¶
如果您需要确定一个模块是否可以在不进行实际导入的情况下导入,那么您应该使用 importlib.util.find_spec()
. ::
import importlib.util
import sys
# For illustrative purposes.
name = 'itertools'
if name in sys.modules:
print(f"{name!r} already in sys.modules")
elif (spec := importlib.util.find_spec(name)) is not None:
# If you chose to perform the actual import ...
module = importlib.util.module_from_spec(spec)
sys.modules[name] = module
spec.loader.exec_module(module)
print(f"{name!r} has been imported")
else:
print(f"can't find the {name!r} module")
直接导入源文件¶
要直接导入python源文件,请使用以下方法(仅限python 3.5和更新版本)::
import importlib.util
import sys
# For illustrative purposes.
import tokenize
file_path = tokenize.__file__
module_name = tokenize.__name__
spec = importlib.util.spec_from_file_location(module_name, file_path)
module = importlib.util.module_from_spec(spec)
sys.modules[module_name] = module
spec.loader.exec_module(module)
实现惰性导入¶
下面的示例演示如何实现延迟导入:
>>> import importlib.util
>>> import sys
>>> def lazy_import(name):
... spec = importlib.util.find_spec(name)
... loader = importlib.util.LazyLoader(spec.loader)
... spec.loader = loader
... module = importlib.util.module_from_spec(spec)
... sys.modules[name] = module
... loader.exec_module(module)
... return module
...
>>> lazy_typing = lazy_import("typing")
>>> #lazy_typing is a real module object,
>>> #but it is not loaded in memory yet.
>>> lazy_typing.TYPE_CHECKING
False
设置导入程序¶
对于导入的深度自定义,您通常希望实现 importer .这意味着管理 finder 和 loader 事情的另一面。对于寻找者来说,根据你的需要,有两种口味可供选择:a meta path finder 或A path entry finder .前者是你要穿的 sys.meta_path
后者是您使用 path entry hook 在 sys.path_hooks
它与 sys.path
可能创建查找器的条目。此示例将向您展示如何注册您自己的导入程序,以便导入使用它们(为了自己创建导入程序,请阅读此包中定义的适当类的文档)::
import importlib.machinery
import sys
# For illustrative purposes only.
SpamMetaPathFinder = importlib.machinery.PathFinder
SpamPathEntryFinder = importlib.machinery.FileFinder
loader_details = (importlib.machinery.SourceFileLoader,
importlib.machinery.SOURCE_SUFFIXES)
# Setting up a meta path finder.
# Make sure to put the finder in the proper location in the list in terms of
# priority.
sys.meta_path.append(SpamMetaPathFinder)
# Setting up a path entry finder.
# Make sure to put the path hook in the proper location in the list in terms
# of priority.
sys.path_hooks.append(SpamPathEntryFinder.path_hook(loader_details))
逼近 importlib.import_module()
¶
import本身是在python代码中实现的,这使得通过importlib公开大多数导入机制成为可能。下面通过提供importlib公开的各种API的近似实现来帮助说明 importlib.import_module()
(python 3.4及更高版本用于importlib,python 3.6及更高版本用于代码的其他部分)。::
import importlib.util
import sys
def import_module(name, package=None):
"""An approximate implementation of import."""
absolute_name = importlib.util.resolve_name(name, package)
try:
return sys.modules[absolute_name]
except KeyError:
pass
path = None
if '.' in absolute_name:
parent_name, _, child_name = absolute_name.rpartition('.')
parent_module = import_module(parent_name)
path = parent_module.__spec__.submodule_search_locations
for finder in sys.meta_path:
spec = finder.find_spec(absolute_name, path)
if spec is not None:
break
else:
msg = f'No module named {absolute_name!r}'
raise ModuleNotFoundError(msg, name=absolute_name)
module = importlib.util.module_from_spec(spec)
sys.modules[absolute_name] = module
spec.loader.exec_module(module)
if path is not None:
setattr(parent_module, child_name, module)
return module