On this page
importlib —导入的实现
3.1 版中的新Function。
Introduction
importlib软件包的目的是双重的。一种是在 Python 源代码中提供import语句的实现(因此,pass扩展来表示import()函数)。这提供了import
的实现,该实现可移植到任何 Python 解释器中。这也提供了比用 Python 以外的其他编程语言实现的实现更容易理解的实现。
第二,此包中公开了实现import的组件,从而使用户更容易创建自己的自定义对象(通常称为importer)以参与导入过程。
See also
import语句的语言参考。
包装的原始规格。自撰写本文以来,某些语义已发生更改(例如,基于sys.modules中的
None
重定向)。import()Function
import语句是此Function的语法糖。
在不区分大小写的平台上导入
定义 Python 源代码编码
新 import 钩
导入:多行和绝对/相对
主模块显式相对导入
隐式名称空间包
导入系统的 ModuleSpec 类型
消除 PYO 文件
多阶段扩展模块初始化
Deterministic pycs
使用 UTF-8 作为默认源编码
PYCRepositories 目录
Functions
importlib.
__import__
(* name , globals = None , locals = None , fromlist =(), level = 0 *)- 内置import()函数的实现。
Note
以编程方式导入模块应使用import_module()代替此Function。
importlib.
import_module
(* name , package = None *)- 导入模块。 * name 参数指定以绝对或相对术语(例如
pkg.mod
或..mod
)导入的模块。如果使用相对术语指定名称,则必须将 package *参数设置为要用作解析软件包名称的锚点的软件包名称(例如import_module('..mod', 'pkg.subpkg')
将导入pkg.mod
)。
- 导入模块。 * name 参数指定以绝对或相对术语(例如
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 *内。如果模块在sys.modules中,则返回
点名没有隐式导入其父项,因为这需要加载它们并且可能不希望这样做。要正确导入子模块,您将需要导入子模块的所有父包,并使用正确的参数* path *。
版本 3.3 中的新Function。
在版本 3.4 中进行了更改:如果未设置__loader__
,请提高ValueError,就像将属性设置为None
一样。
从 3.4 版开始不推荐使用:改为使用importlib.util.find_spec()。
importlib.
invalidate_caches
( )- 使存储在sys.meta_path的查找器的内部缓存无效。如果发现者实现
invalidate_caches()
,那么它将被调用以执行无效操作。如果在程序运行时创建/安装了任何模块,则应调用此函数,以确保所有查找者都将注意到新模块的存在。
- 使存储在sys.meta_path的查找器的内部缓存无效。如果发现者实现
版本 3.3 中的新Function。
importlib.
reload
(* module *)- 重新加载先前导入的* module *。参数必须是模块对象,因此它必须已经成功导入。如果您已使用外部编辑器编辑了模块源文件,并且想在不离开 Python 解释器的情况下try新版本,则这将非常有用。返回值是模块对象(如果重新导入导致将不同的对象放置在sys.modules中,则可以不同)。
当执行reload()时:
重新编译 Python 模块的代码并重新执行模块级代码,从而定义了一组新对象,这些对象pass重用最初加载模块的loader绑定到模块字典中的名称。扩展模块的
init
Function不再被调用。与 Python 中的所有其他对象一样,旧对象仅在其引用计数降至零后才被回收。
模块名称空间中的名称将更新为指向任何新的或更改的对象。
对旧对象的其他引用(例如模块外部的名称)不会反弹以引用新对象,并且如果需要的话,必须在出现它们的每个命名空间中进行更新。
还有其他一些警告:
重新加载模块时,将保留其字典(包含模块的全局变量)。名称的重新定义将覆盖旧的定义,因此这通常不是问题。如果模块的新版本未定义旧版本定义的名称,则保留旧定义。如果此Function维护模块的全局表或对象缓存,则可以利用该模块的优势-使用try语句,它可以测试表的存在并在需要时跳过其初始化:
try:
cache
except NameError:
cache = {}
通常,重新加载内置或动态加载的模块不是很有用。不建议重新加载sys,main,builtins和其他关键模块。在许多情况下,扩展模块不会被初始化一次以上,并且在重新加载时可能会以任意方式失败。
如果一个模块使用from…import…从另一个模块导入对象,则对另一个模块调用reload()不会重新定义从该模块导入的对象-一种解决方法是重新执行from
语句,另一种方法是使用import
和限定名称(* module.name *)代替。
如果模块实例化一个类的实例,则重新加载定义该类的模块不会影响实例的方法定义-它们将 continue 使用旧的类定义。派生类也是如此。
3.4 版的新Function。
在版本 3.7 中进行了更改:当要重装的模块缺少ModuleSpec
时,引发ModuleNotFoundError。
importlib.abc –与导入相关的抽象 Base Class
源代码: Lib/importlib/abc.py
importlib.abc模块包含import使用的所有核心抽象 Base Class。还提供了一些核心抽象 Base Class 的子类,以帮助实现核心 ABC。
ABC hierarchy:
object
+-- Finder (deprecated)
| +-- MetaPathFinder
| +-- PathEntryFinder
+-- Loader
+-- ResourceLoader --------+
+-- InspectLoader |
+-- ExecutionLoader --+
+-- FileLoader
+-- SourceLoader
- 类别
importlib.abc.
Finder
- 表示finder的抽象 Base Class。
自版本 3.3 起不推荐使用:改为使用MetaPathFinder或PathEntryFinder。
- 抽象方法
find_module
(全名,路径=无)- 查找指定模块的loader的抽象方法。最初在 PEP 302中指定,此方法旨在用于sys.meta_path和基于路径的导入子系统。
在版本 3.4 中进行了更改:调用时返回None
而不是引发NotImplementedError。
版本 3.3 中的新Function。
find_spec
((全名,路径,目标=无)- 查找指定模块的spec的抽象方法。如果这是顶级导入,则* path 将为
None
。否则,这是在搜索子包或模块,并且 path *将是父包中path的值。如果找不到规范,则返回None
。传入时,target
是一个模块对象,查找程序可以使用它来对返回的规格进行更有根据的猜测。 importlib.util.spec_from_loader()对于实现具体的MetaPathFinders
可能有用。
- 查找指定模块的spec的抽象方法。如果这是顶级导入,则* path 将为
3.4 版的新Function。
find_module
(全名,路径)
如果定义了find_spec(),则提供向后兼容Function。
在版本 3.4 中进行了更改:调用时返回None
而不是引发NotImplementedError。可以使用find_spec()提供Function。
从 3.4 版开始不推荐使用:改为使用find_spec()。
invalidate_caches
( )- 可选方法,该方法在调用时应使查找程序使用的任何内部缓存无效。当使importlib.invalidate_caches()上所有查找程序的缓存无效时,由importlib.invalidate_caches()使用。
在版本 3.4 中进行了更改:调用时返回None
而不是NotImplemented
。
- 类别
importlib.abc.
PathEntryFinder
- 表示路径查找器的抽象 Base Class。尽管
PathEntryFinder
与MetaPathFinder有一些相似之处,但它只能在PathFinder
提供的基于路径的导入子系统中使用。仅出于兼容性原因,此 ABC 是Finder的子类。
- 表示路径查找器的抽象 Base Class。尽管
版本 3.3 中的新Function。
find_spec
((全名,* target = None *)- 查找指定模块的spec的抽象方法。查找器仅在分配了该模块的path entry内搜索模块。如果找不到规范,则返回
None
。传入时,target
是一个模块对象,发现者可以使用它来对返回的规格进行更有根据的猜测。 importlib.util.spec_from_loader()对于实现具体的PathEntryFinders
可能有用。
- 查找指定模块的spec的抽象方法。查找器仅在分配了该模块的path entry内搜索模块。如果找不到规范,则返回
3.4 版的新Function。
find_loader
(全名)- 查找指定模块的loader的旧方法。返回
(loader, portion)
的 2Tuples,其中portion
是构成名称空间包一部分的文件系统位置的序列。装入程序可以是None
,同时指定portion
以表示文件系统位置对名称空间包的贡献。portion
可以使用一个空列表来表示加载程序不属于名称空间包。如果loader
是None
且portion
是空列表,则找不到命名空间包的加载程序或位置(即找不到模块的任何内容)。
- 查找指定模块的loader的旧方法。返回
如果定义了find_spec(),则将提供向后兼容Function。
在版本 3.4 中进行了更改:返回(None, [])
而不是NotImplementedError。在提供Function时使用find_spec()。
从 3.4 版开始不推荐使用:改为使用find_spec()。
find_module
(全名)- Finder.find_module()的具体实现等效于
self.find_loader(fullname)[0]
。
- Finder.find_module()的具体实现等效于
从 3.4 版开始不推荐使用:改为使用find_spec()。
invalidate_caches
( )- 可选方法,该方法在调用时应使查找程序使用的任何内部缓存无效。当使所有缓存的查找器的缓存无效时,由
PathFinder.invalidate_caches()
使用。
- 可选方法,该方法在调用时应使查找程序使用的任何内部缓存无效。当使所有缓存的查找器的缓存无效时,由
类别
importlib.abc.
Loader
希望支持资源读取的加载程序应实现importlib.abc.ResourceReader指定的get_resource_reader(fullname)
方法。
在 3.7 版中进行了更改:引入了可选的get_resource_reader()
方法。
create_module
(* spec *)- 一种返回模块对象以在导入模块时使用的方法。此方法可能返回
None
,指示默认模块创建语义应该发生。
- 一种返回模块对象以在导入模块时使用的方法。此方法可能返回
3.4 版的新Function。
在版本 3.5 中进行了更改:从 Python 3.6 开始,定义exec_module()时该方法将不是可选的。
exec_module
(* module *)- 导入或重新加载模块时,将在其自己的名称空间中执行模块的抽象方法。调用
exec_module()
时,该模块应已初始化。存在此方法时,必须定义create_module()。
- 导入或重新加载模块时,将在其自己的名称空间中执行模块的抽象方法。调用
3.4 版的新Function。
在 3.6 版中进行了更改:还必须定义create_module()。
load_module
(全名)- 加载模块的旧方法。如果无法加载模块,则引发ImportError,否则返回已加载的模块。
如果所请求的模块已存在于sys.modules中,则应使用该模块并重新加载该模块。否则,加载程序应创建一个新模块,并在开始任何加载之前将其插入sys.modules,以防止从导入中递归。如果加载程序插入了一个模块,但加载失败,则必须由加载程序从sys.modules卸下;在加载程序开始执行之前,sys.modules中已经存在的模块应单独放置(请参见importlib.util.module_for_loader())。
加载程序应在模块上设置几个属性。 (请注意,重新加载模块时,其中某些属性可能会更改):
-
-
- 模块的名称。
-
-
-
- 存储模块数据的路径(未为内置模块设置)。
-
-
-
- 应该/应该存储模块的编译版本的路径(如果该属性不合适,则不设置)。
-
-
-
- 字符串列表,用于指定包中的搜索路径。未在模块上设置此属性。
-
-
-
- 模块/程序包的父程序包。如果模块是顶级模块,则其值为空字符串。 importlib.util.module_for_loader()装饰器可以处理package的详细信息。
-
-
-
- 用于加载模块的加载器。 importlib.util.module_for_loader()装饰器可以处理package的详细信息。
-
exec_module()可用时,将提供向后兼容Function。
在版本 3.4 中更改:调用时提高ImportError而不是NotImplementedError。 exec_module()可用时提供的Function。
从 3.4 版开始不推荐使用:推荐的用于加载模块的 API 为exec_module()(和create_module())。加载程序应实现它而不是 load_module()。当执行 exec_module()时,导入机制将负责 load_module()的所有其他职责。
module_repr
(* module *)- 一种传统方法,在实现时会以字符串形式计算并返回给定模块的 repr。模块类型的默认 repr()将适当地使用此方法的结果。
版本 3.3 中的新Function。
在版本 3.4 中进行了更改:使其成为可选方法,而不是抽象方法。
从版本 3.4 开始不推荐使用:导入机制现在自动执行此操作。
- 类别
importlib.abc.
ResourceReader
- 抽象 Base Class以提供读取* resources *的Function。
从该 ABC 的角度来看,* resource *是包装中附带的二进制工件。通常,这就像是数据文件,位于包装的__init__.py
文件旁边。此类的目的是帮助抽象出对此类数据文件的访问,以使包及其数据文件是否存储在文件中都无关紧要。 zip 文件与文件系统上的文件。
对于此类的任何方法,* resource 参数应为path-like object,从概念上讲它仅表示文件名。这意味着 resource *参数中不应包含子目录路径。这是因为阅读器所针对的软件包的位置充当“目录”。因此,目录和文件名的隐喻分别是包和资源。这也是为什么希望此类的实例直接与特定程序包相关(而不是潜在地表示多个程序包或模块)的原因。
希望支持资源读取的加载程序应该提供一种名为get_resource_reader(fullname)
的方法,该方法返回实现此 ABC 接口的对象。如果全名指定的模块不是软件包,则此方法应返回None。仅当指定的模块是软件包时,才应返回与此 ABC 兼容的对象。
3.7 版中的新Function。
- 抽象方法
open_resource
(资源)- 返回一个打开的file-like object,用于* resource *的二进制读取。
如果找不到资源,则引发FileNotFoundError。
- 抽象方法
resource_path
(资源)- 返回* resource *的文件系统路径。
如果文件系统上不存在该资源,请引发FileNotFoundError。
抽象方法
is_resource
(名称)- 如果命名的* name 被视为资源,则返回
True
。如果 name *不存在,则引发FileNotFoundError。
- 如果命名的* name 被视为资源,则返回
抽象方法
contents
()- 返回包内容中的iterable个字符串。请注意,不需要迭代器返回的所有名称都是实际资源,例如可以返回is_resource()为 Pseudo 名称。
允许返回非资源名称是为了允许先验地知道包及其资源的存储方式,并且非资源名称将很有用。例如,允许返回子目录名称,以便当已知包和资源存储在文件系统上时,可以直接使用那些子目录名称。
abstract 方法返回无项目的可迭代对象。
从 3.7 版开始不推荐使用:不推荐使用此 ABC,以支持passimportlib.abc.ResourceReader加载资源。
- 抽象方法
get_data
(路径)
在版本 3.4 中更改:提高OSError而不是NotImplementedError。
类别
importlib.abc.
InspectLoader
get_code
(全名)- 返回模块的代码对象,或者返回
None
(如果该模块没有代码对象)(例如,内置模块的情况)。如果加载程序找不到请求的模块,请引发ImportError。
- 返回模块的代码对象,或者返回
Note
尽管该方法具有默认实现,但建议为性能起见将其覆盖。
在版本 3.4 中进行了更改:不再是抽象的,并且提供了具体的实现。
- 抽象方法
get_source
(全名)- 返回模块源的抽象方法。它使用universal newlines作为文本字符串返回,将所有可识别的行分隔符转换为
'\n'
个字符。如果没有可用的来源(例如内置模块),则返回None
。如果加载程序找不到指定的模块,则引发ImportError。
- 返回模块源的抽象方法。它使用universal newlines作为文本字符串返回,将所有可识别的行分隔符转换为
在版本 3.4 中更改:提高ImportError而不是NotImplementedError。
is_package
(全名)- 如果模块是包,则返回真值的抽象方法,否则返回假值。如果loader找不到模块,则引发ImportError。
在版本 3.4 中更改:提高ImportError而不是NotImplementedError。
- 静态
source_to_code
(数据,路径='')- 从 Python 源创建代码对象。
- data *参数可以是compile()函数支持的值(即字符串或字节)。 * path *参数应该是源代码所源自的“路径”,它可以是抽象概念(例如 zip 文件中的位置)。
使用后续代码对象,可以pass运行exec(code, module.__dict__)
在模块中执行它。
3.4 版的新Function。
在版本 3.5 中更改:使方法静态。
exec_module
(* module *)
3.4 版的新Function。
load_module
(全名)
自 3.4 版起已弃用:改为使用exec_module()。
类别
importlib.abc.
ExecutionLoader
- 从InspectLoader继承的抽象 Base Class,该 Base Class 在实现时有助于将模块作为脚本执行。 ABC 代表可选的 PEP 302协议。
抽象方法
get_filename
(全名)- 一种抽象方法,该方法返回指定模块的file值。如果没有可用路径,则引发ImportError。
如果源代码可用,则该方法应返回源文件的路径,而不管是否使用字节码加载模块。
在版本 3.4 中更改:提高ImportError而不是NotImplementedError。
- 类别
importlib.abc.
FileLoader
(全名,路径)- 从ResourceLoader和ExecutionLoader继承的抽象 Base Class,提供ResourceLoader.get_data()和ExecutionLoader.get_filename()的具体实现。
- fullname *参数是加载程序要处理的模块的完全解析名称。 * path *参数是模块文件的路径。
版本 3.3 中的新Function。
name
- 加载程序可以处理的模块的名称。
path
- 模块文件的路径。
load_module
(全名)- 呼叫 super 的
load_module()
。
- 呼叫 super 的
从 3.4 版开始不推荐使用:改为使用Loader.exec_module()。
抽象方法
get_filename
(全名)- Returns path.
抽象方法
get_data
(路径)- 将* path *读取为二进制文件,并从中返回字节。
类别
importlib.abc.
SourceLoader
- 用于实现源(和可选的字节码)文件加载的抽象 Base Class。该类继承自ResourceLoader和ExecutionLoader,需要实现:
-
ExecutionLoader.get_filename()
- 应该只返回源文件的路径;不支持无源加载。
此类定义的抽象方法是添加可选的字节码文件支持。不实现这些可选方法(或导致它们引发NotImplementedError)将导致加载程序仅使用源代码。实现这些方法使加载程序可以处理源和字节码文件;它不允许仅提供字节码的“无源”加载。字节码文件是一种优化方法,它pass删除 Python 编译器的解析步骤来加快加载速度,因此没有公开特定于字节码的 API。
path_stats
(* path *)- 可选的抽象方法,该方法返回包含有关指定路径的元数据的dict。支持的字典键是:
'mtime'
(必填):表示源代码修改时间的整数或浮点数;'size'
(可选):源代码的大小(以字节为单位)。
字典中的任何其他键都将被忽略,以允许将来扩展。如果无法处理该路径,则引发OSError。
版本 3.3 中的新Function。
在版本 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
(全名)- InspectLoader.get_code()的具体实现。
exec_module
(* module *)- Loader.exec_module()的具体实现。
3.4 版的新Function。
load_module
(全名)- Loader.load_module()的具体实现。
从 3.4 版开始不推荐使用:改为使用exec_module()。
get_source
(全名)is_package
(全名)- InspectLoader.is_package()的具体实现。如果在删除文件 extensions 时,其模块路径(由ExecutionLoader.get_filename()提供)是名为
__init__
的文件,并且该模块名称本身不以__init__
结尾,则将模块确定为包。
- InspectLoader.is_package()的具体实现。如果在删除文件 extensions 时,其模块路径(由ExecutionLoader.get_filename()提供)是名为
importlib.resources –资源
源代码: Lib/importlib/resources.py
3.7 版中的新Function。
该模块利用 Python 的 import 系统提供对* packages 中的 resources *的访问。如果可以导入软件包,则可以访问该软件包中的资源。可以以二进制或文本模式打开或读取资源。
资源大致类似于目录中的文件,但请记住,这只是一个隐喻,这一点很重要。资源和包 不必 作为文件系统上的物理文件和目录存在。
Note
该模块提供的Function类似于pkg_resources 基本资源访问,而没有该程序包的性能开销。这使阅读包中包含的资源变得更加容易,并且语义更加稳定和一致。
此模块的独立 backport 提供有关using importlib.resources和从 pkg_resources 迁移到 importlib.resources的更多信息。
希望支持资源读取的加载程序应实现importlib.abc.ResourceReader指定的get_resource_reader(fullname)
方法。
定义了以下类型。
importlib.resources.
Package
Package
类型定义为Union[str, ModuleType]
。这意味着在函数描述接受Package
的地方,您可以传入字符串或模块。模块对象必须具有可解析的__spec__.submodule_search_locations
而不是None
。
importlib.resources.
Resource
- 此类型描述传递给此程序包中各个函数的资源名称。定义为
Union[str, os.PathLike]
。
- 此类型描述传递给此程序包中各个函数的资源名称。定义为
以下Function可用。
importlib.resources.
open_binary
(* package , resource *)- 打开以二进制方式读取* package 中的 resource *。
- package *是符合
Package
要求的名称或模块对象。 * resource 是要在 package *中打开的资源的名称;它可能不包含路径分隔符,并且可能没有子资源(即它不能是目录)。该函数返回一个typing.BinaryIO
实例,一个二进制 I/O 流已打开以供读取。
importlib.resources.
open_text
(* package , resource , encoding ='utf-8', errors ='strict'*)- 打开以阅读* package 中的 resource *的文本。默认情况下,该资源被打开以作为 UTF-8 读取。
- package *是符合
Package
要求的名称或模块对象。 * resource 是要在 package *中打开的资源的名称;它可能不包含路径分隔符,并且可能没有子资源(即它不能是目录)。 * encoding 和 errors 具有与内置open()相同的含义。
此函数返回一个typing.TextIO
实例,一个文本 I/O 流已打开以供读取。
importlib.resources.
read_binary
(* package , resource *)- 以
bytes
读取并返回* package 中的 resource *的内容。
- 以
- package *是符合
Package
要求的名称或模块对象。 * resource 是要在 package *中打开的资源的名称;它可能不包含路径分隔符,并且可能没有子资源(即它不能是目录)。此函数以bytes的形式返回资源的内容。
importlib.resources.
read_text
(* package , resource , encoding ='utf-8', errors ='strict'*)- 以
str
的形式读取并返回* package 中的 resource *的内容。默认情况下,内容被读取为严格的 UTF-8.
- 以
- package *是符合
Package
要求的名称或模块对象。 * resource 是要在 package *中打开的资源的名称;它可能不包含路径分隔符,并且可能没有子资源(即它不能是目录)。 * encoding 和 errors 具有与内置open()相同的含义。此函数以str的形式返回资源的内容。
importlib.resources.
path
(* package , resource *)- 将路径返回到* resource *作为实际的文件系统路径。此函数返回一个上下文 Management 器以用于with语句。上下文 Management 器提供了一个pathlib.Path对象。
退出上下文 Management 器会清除需要从中提取资源时创建的任何临时文件。一个 zip 文件。
- package *是符合
Package
要求的名称或模块对象。 * resource 是要在 package *中打开的资源的名称;它可能不包含路径分隔符,并且可能没有子资源(即它不能是目录)。
importlib.resources.
is_resource
(* package , name *)- 如果程序包中有一个名为* name *的资源,则返回
True
,否则返回False
。请记住,目录不是“ *”资源! * package *是符合Package
要求的名称或模块对象。
- 如果程序包中有一个名为* name *的资源,则返回
importlib.resources.
contents
(* package *)- 返回包装中命名项的可迭代项。迭代器返回str个资源(例如文件)和非资源(例如目录)。该可迭代对象不会递归到子目录中。
- package *是符合
Package
要求的名称或模块对象。
importlib.machinery –导入程序和路径钩子
源代码: Lib/importlib/machinery.py
该模块包含帮助import查找和加载模块的各种对象。
importlib.machinery.
SOURCE_SUFFIXES
- 代表源模块识别的文件后缀的字符串列表。
版本 3.3 中的新Function。
importlib.machinery.
DEBUG_BYTECODE_SUFFIXES
- 代表未优化字节码模块的文件后缀的字符串列表。
版本 3.3 中的新Function。
从版本 3.5 开始不推荐使用:改为使用BYTECODE_SUFFIXES。
importlib.machinery.
OPTIMIZED_BYTECODE_SUFFIXES
- 代表优化后的字节码模块的文件后缀的字符串列表。
版本 3.3 中的新Function。
从版本 3.5 开始不推荐使用:改为使用BYTECODE_SUFFIXES。
importlib.machinery.
BYTECODE_SUFFIXES
- 代表字节码模块(包括前导点)的已识别文件后缀的字符串列表。
版本 3.3 中的新Function。
在版本 3.5 中进行了更改:该值不再取决于__debug__
。
importlib.machinery.
EXTENSION_SUFFIXES
- 代表扩展模块识别的文件后缀的字符串列表。
版本 3.3 中的新Function。
importlib.machinery.
all_suffixes
( )- 返回表示标准导入机制识别的模块的所有文件后缀的字符串组合列表。这是代码的帮助者,它仅需要知道文件系统路径是否潜在地引用了模块,而无需任何有关模块类型的详细信息(例如inspect.getmodulename())。
版本 3.3 中的新Function。
- 类别
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()
- 类别
importlib.machinery.
FrozenImporter
- importer用于冻结的模块。此类实现importlib.abc.MetaPathFinder和importlib.abc.InspectLoader ABC。
此类仅定义类方法以减轻实例化的需求。
在版本 3.4 中更改:获得了create_module()
和exec_module()
方法。
- 类别
importlib.machinery.
WindowsRegistryFinder
- Finder用于 Windows 注册表中语句的模块。此类实现importlib.abc.MetaPathFinder ABC。
此类仅定义类方法以减轻实例化的需求。
版本 3.3 中的新Function。
自版本 3.6 起不推荐使用:而是使用site配置。默认情况下,Future 版本的 Python 可能不会启用此查找程序。
- 类别
importlib.machinery.
PathFinder
- Finder用于sys.path和包
__path__
属性。此类实现importlib.abc.MetaPathFinder ABC。
- Finder用于sys.path和包
此类仅定义类方法以减轻实例化的需求。
- 类方法
find_spec
(全名,路径=无,目标=无)- try为sys.path或* path 上的 fullname *指定的模块寻找spec的类方法。对于搜索到的每个路径条目,都会检查sys.path_importer_cache。如果找到非伪对象,则将其用作路径查找器来查找要搜索的模块。如果在sys.path_importer_cache中找不到条目,则在sys.path_hooks中搜索路径条目的查找器,如果找到了,则将其与模块查询一起存储在sys.path_importer_cache中。如果找不到查找程序,则
None
都存储在缓存中并返回。
- try为sys.path或* path 上的 fullname *指定的模块寻找spec的类方法。对于搜索到的每个路径条目,都会检查sys.path_importer_cache。如果找到非伪对象,则将其用作路径查找器来查找要搜索的模块。如果在sys.path_importer_cache中找不到条目,则在sys.path_hooks中搜索路径条目的查找器,如果找到了,则将其与模块查询一起存储在sys.path_importer_cache中。如果找不到查找程序,则
3.4 版的新Function。
在版本 3.5 中进行了更改:如果当前工作目录(由空字符串表示)不再有效,则返回None
,但没有值被缓存在sys.path_importer_cache中。
- 类方法
find_module
(全名,路径=无)- find_spec()周围的旧包装。
从 3.4 版开始不推荐使用:改为使用find_spec()。
- 分类方法
invalidate_caches
()- 在定义该方法的sys.path_importer_cache中存储的所有查找器上调用importlib.abc.PathEntryFinder.invalidate_caches()。否则,将sys.path_importer_cache中设置为
None
的条目删除。
- 在定义该方法的sys.path_importer_cache中存储的所有查找器上调用importlib.abc.PathEntryFinder.invalidate_caches()。否则,将sys.path_importer_cache中设置为
在 3.7 版中进行了更改:删除了sys.path_importer_cache中的None
条目。
在版本 3.4 中进行了更改:在sys.path_hooks中使用当前工作目录''
调用对象(即空字符串)。
-
- class *
importlib.machinery.
FileFinder
(* path ,* loader_details *)
- importlib.abc.PathEntryFinder的具体实现可缓存文件系统中的结果。
- class *
path *参数是查找器负责搜索的目录。
loader_details *参数是可变数量的 2 项 Tuples,每个 Tuples 包含一个加载程序以及该加载程序可以识别的文件后缀序列。加载程序应该是可调用的,可以接受模块名称和找到的文件路径的两个参数。
查找器将根据需要缓存目录内容,对每个模块进行统计调用以验证缓存是否过时。由于缓存的陈旧性取决于文件系统的 os 状态信息的粒度,因此存在潜在的竞争条件,即搜索模块,创建新文件,然后搜索新文件代表的模块。如果操作发生得足够快以适合 stat 调用的粒度,则模块搜索将失败。为防止这种情况发生,在动态创建模块时,请确保调用importlib.invalidate_caches()。
版本 3.3 中的新Function。
path
- 查找器将搜索的路径。
find_spec
((全名,* target = None *)- try在path中找到处理全名的规范。
3.4 版的新Function。
find_loader
(全名)- try找到要在path内处理* fullname *的加载程序。
invalidate_caches
( )- 清除内部缓存。
类方法
path_hook
(** loader_details *)- 返回用于sys.path_hooks的闭包的类方法。闭包使用直接给闭包指定的路径参数返回FileFinder的实例,并间接使用* loader_details *返回。
如果闭包的参数不是现有目录,则引发ImportError。
- 类别
importlib.machinery.
SourceFileLoader
(全名,路径)- pass将importlib.abc.FileLoader子类化并提供其他方法的一些具体实现,可以实现importlib.abc.SourceLoader的具体实现。
版本 3.3 中的新Function。
name
- 该加载程序将处理的模块的名称。
path
- 源文件的路径。
is_package
(全名)- 如果path似乎是用于包装的,则返回
True
。
- 如果path似乎是用于包装的,则返回
path_stats
(* path *)set_data
(* path , data *)load_module
(* name = None *)- importlib.abc.Loader.load_module()的具体实现是可选的,其中指定要加载的模块的名称。
自版本 3.6 起不推荐使用:改为使用importlib.abc.Loader.exec_module()。
- 类别
importlib.machinery.
SourcelessFileLoader
(全名,路径)- importlib.abc.FileLoader的具体实现可以导入字节码文件(即不存在源代码文件)。
请注意,直接使用字节码文件(因此不是源代码文件)会禁止您的模块在所有更改字节码格式的 Python 实现或新版本的 Python 中使用。
版本 3.3 中的新Function。
name
- 加载程序将处理的模块的名称。
path
- 字节码文件的路径。
is_package
(全名)- 确定模块是否为基于path的程序包。
get_code
(全名)get_source
(全名)- 返回
None
,因为使用此加载程序时字节码文件没有源。
- 返回
load_module
(* name = None *)
importlib.abc.Loader.load_module()的具体实现是可选的,其中指定要加载的模块的名称。
自版本 3.6 起不推荐使用:改为使用importlib.abc.Loader.exec_module()。
- 类别
importlib.machinery.
ExtensionFileLoader
(全名,路径)- 扩展模块的importlib.abc.ExecutionLoader的具体实现。
- fullname *参数指定加载程序要支持的模块的名称。 * path *参数是扩展模块文件的路径。
版本 3.3 中的新Function。
name
- 加载程序支持的模块的名称。
path
- 扩展模块的路径。
create_module
(* spec *)- 根据 PEP 489从给定的规范创建模块对象。
3.5 版中的新Function。
exec_module
(* module *)- 根据 PEP 489初始化给定的模块对象。
3.5 版中的新Function。
is_package
(全名)- 如果文件路径指向基于EXTENSION_SUFFIXES的程序包的
__init__
模块,则返回True
。
- 如果文件路径指向基于EXTENSION_SUFFIXES的程序包的
get_code
(全名)- 由于扩展模块缺少代码对象,因此返回
None
。
- 由于扩展模块缺少代码对象,因此返回
get_source
(全名)- 返回
None
,因为扩展模块没有源代码。
- 返回
get_filename
(全名)- Returns path.
3.4 版的新Function。
-
- class *
importlib.machinery.
ModuleSpec
(* name , loader ,**,* origin = None , loader_state = None , is_package = None *)
- 模块与导入系统有关的状态的规范。通常将其公开为模块的
__spec__
属性。在下面的描述中,括号中的名称给出了直接在模块对象上可用的相应属性。例如。module.__spec__.origin == module.__file__
。但是请注意,虽然* values *通常是等效的,但是由于两个对象之间没有同步,因此它们可能会有所不同。因此,可以在运行时更新模块的__path__
,而这不会自动反映在__spec__.submodule_search_locations
中。
- class *
3.4 版的新Function。
name
( __name__
)
一个字符串,表示模块的标准名称。
loader
( __loader__
)
用于加载的加载器。对于名称空间包,应将其设置为None
。
origin
( __file__
)
加载模块的位置的名称,例如“内置”用于内置模块,文件名用于从源加载的模块。通常应设置“ origin”,但它可以是None
(默认值),表示未指定(例如,用于名称空间包)。
submodule_search_locations
( __path__
)
字符串列表,用于在哪里找到子模块(如果为软件包,则为None
)。
loader_state
容器,用于在加载过程中使用额外的模块特定数据(或None
)。
cached
( __cached__
)
编译模块应存储的字符串(或None
)。
parent
( __package__
)
(只读)模块作为子模块所属的软件包的全限定名称(或None
)。
has_location
布尔值,指示模块的“来源”属性是否引用可加载位置。
importlib.util –import 商的 Util 代码
此模块包含有助于构建importer的各种对象。
importlib.util.
MAGIC_NUMBER
- 代表字节码版本号的字节。如果您需要有关加载/写入字节码的帮助,请考虑importlib.abc.SourceLoader。
3.4 版的新Function。
importlib.util.
cache_from_source
(* path , debug_override = None ,**,* optimization = None *)- 将 PEP 3147/ PEP 488路径返回到与源* 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)。
- 将 PEP 3147/ PEP 488路径返回到与源* path 关联的字节编译文件。例如,如果 path *为
optimization *参数用于指定字节码文件的优化级别。空字符串表示没有优化,因此
/foo/bar/baz.py
的_optimization 为''
会导致/foo/bar/__pycache__/baz.cpython-32.pyc
的字节码路径。None
导致使用解释器的优化级别。使用任何其他值的字符串表示形式,因此/foo/bar/baz.py
(优化)为2
会导致字节码路径为/foo/bar/__pycache__/baz.cpython-32.opt-2.pyc
。 * optimization *的字符串表示形式只能是字母数字,否则将引发ValueError。debug_override 参数已被弃用,可用于覆盖
__debug__
的系统值。True
值等效于将 optimization 设置为空字符串。False
的值与将 optimization 设置为1
的值相同。如果两个 debug_override 和 optimization *都不都是None
,则引发TypeError。
3.4 版的新Function。
在版本 3.5 中进行了更改:添加了* optimization 参数,并且不建议使用 debug_override *参数。
在版本 3.6 中更改:接受path-like object。
importlib.util.
source_from_cache
(* path *)- 给定 PEP 3147文件名的* path ,返回相关的源代码文件路径。例如,如果 path *是
/foo/bar/__pycache__/baz.cpython-32.pyc
,则返回的路径将是/foo/bar/baz.py
。 * path *不必存在,但是,如果它不符合 PEP 3147或 PEP 488格式,则会引发ValueError。如果未定义sys.implementation.cache_tag
,则引发NotImplementedError。
- 给定 PEP 3147文件名的* path ,返回相关的源代码文件路径。例如,如果 path *是
3.4 版的新Function。
在版本 3.6 中更改:接受path-like object。
importlib.util.
decode_source
(* source_bytes *)- 解码代表源代码的给定字节,并使用通用换行符将其作为字符串返回(按importlib.abc.InspectLoader.get_source()的要求)。
3.4 版的新Function。
importlib.util.
resolve_name
(* name , package *)- 将相对模块名称解析为绝对名称。
如果“名称”没有前导点,则仅返回“名称”。这允许使用诸如importlib.util.resolve_name('sys', __package__)
之类的用法,而无需检查是否需要 package 参数。
如果 name 是相对模块名称,但 package 是错误的值(例如None
或空字符串),则引发ValueError。还提出了ValueError的相对名称,该相对名称会逸出其包含的数据包(例如,从spam
数据包中请求..bacon
)。
版本 3.3 中的新Function。
importlib.util.
find_spec
(* name , package = None *)- 查找模块的spec,可以相对于指定的“包”名称进行查找。如果模块位于sys.modules,则返回
sys.modules[name].__spec__
(除非规范为None
或未设置,在这种情况下ValueError升高)。否则,将使用sys.meta_path进行搜索。如果找不到规格,则返回None
。
- 查找模块的spec,可以相对于指定的“包”名称进行查找。如果模块位于sys.modules,则返回
如果 name 用于子模块(包含点),则会自动导入父模块。
name 和 package 的工作方式与import_module()
相同。
3.4 版的新Function。
在 3.7 版中进行了更改:如果 package 实际上不是包(即缺少path属性),则提起ModuleNotFoundError而不是AttributeError。
importlib.util.
module_from_spec
(* spec *)- 根据 spec 和spec.loader.create_module创建一个新模块。
如果spec.loader.create_module不返回None
,则不会重置任何先前存在的属性。另外,如果在访问 spec 或在模块上设置属性时触发,则不会引发AttributeError。
此Function优于使用types.ModuleType创建新模块,因为 spec 用于在模块上设置尽可能多的导入控制属性。
3.5 版中的新Function。
@
importlib.util.
module_for_loader
- decorator用于importlib.abc.Loader.load_module()处理选择要加载的适当模块对象。装饰的方法应该具有一个带有两个位置参数(例如
load_module(self, module)
)的调用签名,第二个参数将是加载器要使用的模块 object 。请注意,由于有两个参数,装饰器将无法在静态方法上使用。
- decorator用于importlib.abc.Loader.load_module()处理选择要加载的适当模块对象。装饰的方法应该具有一个带有两个位置参数(例如
装饰的方法将采用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 开始不推荐使用:导入机制现在直接执行此Function提供的所有Function。
@
importlib.util.
set_loader
- decorator代表importlib.abc.Loader.load_module()在返回的模块上设置loader属性。如果属性已设置,则装饰器不执行任何操作。假定包装方法的第一个位置参数(即
self
)是loader应该设置的。
- decorator代表importlib.abc.Loader.load_module()在返回的模块上设置loader属性。如果属性已设置,则装饰器不执行任何操作。假定包装方法的第一个位置参数(即
在版本 3.4 中进行了更改:如果设置为None
,则设置__loader__
,就好像该属性不存在一样。
从版本 3.4 开始不推荐使用:导入机制将自动处理此问题。
@
importlib.util.
set_package
- decorator代表importlib.abc.Loader.load_module()在返回的模块上设置package属性。如果设置了package且其值为
None
以外的值,则不会更改。
- decorator代表importlib.abc.Loader.load_module()在返回的模块上设置package属性。如果设置了package且其值为
从版本 3.4 开始不推荐使用:导入机制将自动处理此问题。
importlib.util.
spec_from_loader
(* name , loader ,**,* origin = None , is_package = None *)- 用于基于加载程序创建
ModuleSpec
实例的工厂函数。参数的含义与 ModuleSpec 的含义相同。该函数使用可用的loader API(例如InspectLoader.is_package()
)来填充规范上缺少的任何信息。
- 用于基于加载程序创建
3.4 版的新Function。
importlib.util.
spec_from_file_location
(* name , location ,**,* loader = None , submodule_search_locations = None *)- 一种工厂Function,用于基于文件的路径创建
ModuleSpec
实例。缺少的信息将pass使用加载程序 API 以及模块将基于文件的含义填充在规范中。
- 一种工厂Function,用于基于文件的路径创建
3.4 版的新Function。
在版本 3.6 中更改:接受path-like object。
importlib.util.
source_hash
(* source_bytes *)- 返回* source_bytes *的哈希值作为字节。基于散列的
.pyc
文件将相应源文件内容的source_hash()嵌入其标题中。
- 返回* source_bytes *的哈希值作为字节。基于散列的
3.7 版中的新Function。
-
- class *
importlib.util.
LazyLoader
(* loader *)
- 一个类,该类推迟模块的加载程序的执行,直到该模块访问了属性。
- class *
此类“仅**”与定义exec_module()的装载程序一起使用,以控制所需的模块类型。出于同样的原因,加载器的create_module()方法必须返回None
或可以更改其__class__
属性的类型,而不使用slots。最后,替换无法放置到sys.modules中的对象的模块将无法正常工作,因为无法安全地在整个解释器中正确替换模块引用;如果检测到这样的替换,则引发ValueError。
Note
对于启动时间很关键的项目,如果从未使用过,则此类可潜在地最大程度地减少加载模块的成本。对于启动时间不是必需的项目,由于在加载过程中创建的错误消息被推迟从而在上下文之外发生,因此不建议大量使用此类。
3.5 版中的新Function。
在版本 3.6 中更改:开始调用create_module(),删除了importlib.machinery.BuiltinImporter和importlib.machinery.ExtensionFileLoader的兼容性警告。
- 类方法
factory
(加载器)- 返回创建惰性加载程序的可调用方法的静态方法。这旨在用于pass类而不是实例传递加载程序的情况。
suffixes = importlib.machinery.SOURCE_SUFFIXES
loader = importlib.machinery.SourceFileLoader
lazy_loader = importlib.util.LazyLoader.factory(loader)
finder = importlib.machinery.FileFinder(path, (lazy_loader, suffixes))
Examples
Importing programmatically
要以编程方式导入模块,请使用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 商
对于导入的深度自定义,您通常需要实现importer。这意味着要同时 Management 事物的finder和loader。对于查找者,根据您的需求有两种选择:元路径查找器或路径查找器。前者是您要放在sys.meta_path上的内容,而后者是您使用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))
Approximating importlib.import_module()
导入本身是用 Python 代码实现的,因此可以pass importlib 公开大多数导入机制。以下内容pass提供importlib.import_module()的大概实现来帮助说明 importlib 公开的各种 API(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