importlib- 执行-Importing Modules(Python教程)(参考资料)
importlib
– 实施 import
版本3.1.
源代码:LIB /导入库/ __ init__.py
介绍
的目的importlib
包装是双重的。一个是在Python源代码中提供import
语句的实现(因此,扩展名为__import__()
函数)。这提供了import
它可以移植到任何Python解释器。这也提供了一种比Python以外的编程语言更容易理解的实现.
二,实现import
的组件暴露在这个包中,使用户更容易创建自己的自定义对象(统称为导入器)参与导入过程.
参见
- 导入声明
import
声明的语言参考- 包装规格
- 包的原始规格。自撰写本文档以来,一些语义已发生变化(例如,基于重定向
None
在sys.modules
). __import__()
功能import
语句是这个函数的语法糖.- PEP 235
- 导入不区分大小写的平台
- PEP 263
- 定义Python源代码编码
- PEP 302
- 新的导入钩
- PEP328
- 进口:多线和绝对/相对
- 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
)。如果名称是以相对术语指定的,则必须将package参数设置为包的名称,该包作为解析包名称的锚点(例如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
的finders的内部缓存无效。如果取景器实现invalidate_caches()
然后它将被调用以执行失效。如果在程序运行时创建/安装任何模块,应调用此函数以保证所有查找程序都会注意到新模块的存在.3.3版本中的新功能
importlib.
reload
// (module)- 重新装入先前进口的module。参数必须是模块对象,因此必须先成功导入。如果您使用外部编辑器编辑了模块源文件并希望在不离开Python解释器的情况下试用新版本,这将非常有用。返回值是模块对象(如果重新导入导致将不同的对象放在
sys.modules
).reload()
执行时:- 重新编译Python模块的代码并重新执行模块级代码,通过重用 loader 最初加载了模块。扩展模块的
init
功能不是第二次调用. - 与Python中的所有其他对象一样,旧对象只有在引用计数降为零后才会被回收.
- 模块命名空间中的名称将更新为指向任何新的或更改的对象.
- 其他引用对旧对象(例如模块外部的名称)不会反弹以引用新对象,如果需要,必须在每个命名空间中更新它们.
还有其他一些注意事项:
重新加载模块时,会保留其字典(包含模块的全局变量)。名称的重新定义将覆盖旧的定义,因此这通常不是问题。如果新版本的amodule没有定义旧版本定义的名称,则旧的定义仍然存在。如果它保留了一个全局表或对象缓存,则该功能可以用于模块的优势 – 使用
try
语句可以测试表的存在并跳过初始化ifdesired:try: cache except NameError: cache = {}
重新加载内置或动态加载的模块通常不是很有用。重装
sys
,__main__
,builtins
和其他关键模块不推荐。在许多情况下,扩展模块不是设计为不止一次初始化,并且可能在重新加载时以任意方式失败.如果一个模块使用
from
…import
…从另一个模块导入对象,则为另一个模块调用reload()
不会重新定义从它导入的对象 – 解决这个问题的方法之一就是 -执行from
声明,另一种是使用import
和限定名称(module.name)代替如果模块实例化类的实例,则重新加载定义类的模块不会影响实例的方法定义 – 他们继续使用旧的类定义。派生类也是如此.
版本3.4.
更改版本3.7:
ModuleNotFoundError
重新加载模块时出现错误ModuleSpec
. - 重新编译Python模块的代码并重新执行模块级代码,通过重用 loader 最初加载了模块。扩展模块的
importlib.abc
– 与导入相关的抽象基类
源代码:LIB /导入库/ abc.py
importlib.abc
module包含import
。还提供了核心抽象基类的一些子类来帮助实现核心ABC .
ABC等级:
object
+-- Finder (deprecated)
| +-- MetaPathFinder
| +-- PathEntryFinder
+-- Loader
+-- ResourceLoader --------+
+-- InspectLoader |
+-- ExecutionLoader --+
+-- FileLoader
+-- SourceLoader
- class
importlib.abc.
MetaPathFinder
- 表示元路径查找器的抽象基类。为了兼容性,这是版本3.3中的
Finder
.的新类.
find_spec
(fullname, path, target=None)- 一种抽象方法,用于查找指定模块的 spec 。如果这是顶级导入,path将
None
。否则,这是搜索子包ormodule和path将是来自theparent包的__path__
的值。如果找不到规格,则返回None
。传入时,target
是一个模块对象,查找器可以用来对返回的规格进行更有根据的猜测.新版本3.4.
- class
importlib.abc.
PathEntryFinder
- 表示路径条目查找器的抽象基类。虽然与
MetaPathFinder
,PathEntryFinder
有一些相似之处,但仅适用于PathFinder
提供的基于路径的导入子系统。出于兼容性原因,这个ABC是Finder
的子类.3.3版本中的新文件
find_spec
// (fullname, target=None)- 一种抽象方法找到 spec 指定的模块。取景器将仅在路径条目中搜索该模块。如果找不到规格,则返回
None
。当传入时,target
是一个模块对象,寻找者可以用来制作一个更有教育意义的关于返回什么规格的文件.新版本3.4.
find_loader
(fullname)- 为指定的模块找到加载器的遗留方法。返回
(loader, portion)
的2元组,其中portion
是一系列文件系统位置,有助于命名空间包的一部分。装载机可能是None
同时指定portion
将文件系统位置的贡献设置为namespacepackage。可以使用空列表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
()- 一个可选的方法,当被调用时,应该使finder使用的任何内部缓存无效。在使所有缓存的查找器的缓存无效时
PathFinder.invalidate_caches()
使用.
- class
importlib.abc.
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__
- 指定apackage中搜索路径的字符串列表。此属性未在模块上设置.
-
__package__
- 模块/包的父包。如果模块是顶级的,则它具有空字符串的值。
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()
)。加载器应该实现它而不是load_module()。当exec_module()实现时,导入机器负责load_module()的所有其他职责. -
module_repr
(module )- 一种遗留方法,在实现时计算并返回给出的模块的repr,作为字符串。模块类型的默认repr()将使用此方法的结果.
3.3版本中的新功能
更改版本3.4:可选而不是抽象方法.
自版本3.4:现在进口机器自动处理这个
- class
importlib.abc.
ResourceReader
- 一个抽象基类提供阅读的能力resources.
从这个ABC的角度来看,resource是包中提供的二进制工件。通常这类似于
__init__.py
包的文件。该类的目的是帮助抽象出对这些数据文件的访问,以使包和它的数据文件存储在例如数据文件中无关紧要。文件系统上的zip文件.对于这个类的任何方法,resource参数应该是路径类对象它代表概念上只是一个文件名。这意味着resource论点。这是因为读者所用的包的位置,充当“目录”。因此,目录和文件名的隐喻分别是包和资源。这也是为什么这个类的实例应该直接与特定包相关联(而不是可能代表多个包或模块).
希望支持资源读取的加载器有望提供一种称为
get_resource_loader(fullname)
它返回了实现这个ABC界面的对象。如果fullname指定的模块不是包,则此方法应返回None
。只有当指定的模块是包时,才能返回与此ABC兼容的对象.版本3.7.
- abstractmethod
open_resource
(resource) - 返回一个打开的文件般的对象对于resource.
的二进制读取如果找不到资源,
FileNotFoundError
israised.
- abstractmethod
resource_path
(resource) - 返回文件系统路径去resource.
如果资源在文件系统上没有具体存在,则引发
FileNotFoundError
.
- abstractmethod
is_resource
(name) - 返回
True
如果命名name被视为资源.FileNotFoundError
如果name不存在。
- abstractmethod
contents
() - 返回可迭代包裹内容的字符串。请注意,迭代器返回的所有名称都不需要是实际资源,例如:返回
is_resource()
会是假的.允许返回非资源名称是为了允许包装及其资源的存储方式是先验已知的,并且非资源名称是有用的。例如,允许返回子目录名称,以便在知道包时和资源存储在文件系统上,然后这些子目录名可以直接使用.
抽象方法返回一个无项目的迭代.
- abstractmethod
- class
importlib.abc.
ResourceLoader
- 加载器的抽象基类实现了可选的 PEP 302 从storageback-end.
从版本3.7开始不推荐使用:这个ABC被弃用,支持通过
importlib.abc.ResourceReader
.- abstractmethod
get_data
(path) - 返回字节的抽象方法数据位于path.Loaders具有类似文件的存储后端,允许存储任意数据库,实现这种抽象方法,直接访问存储的数据。
OSError
如果找不到path就会被提出来。path应该使用模块的__file__
属性或包中的项来构造__path__
.在版本3.4中更改:引发
OSError
而不是NotImplementedError
.
- abstractmethod
- class
importlib.abc.
InspectLoader
- 加载器的抽象基类,它实现了 PEP 302 协议的加载器检查模块.
get_code
(fullname)- 返回模块的代码对象,或
None
如果模块没有代码对象(如同例如,内置模块就是这种情况。如果装载机找不到所需的模块,请举起ImportError
注意
加载任意资源的协议虽然该方法有一个默认的实现,但如果可能的话,建议重写一下
更改版本3.4:不再抽象,并提供具体实现.
- abstractmethod
get_source
(fullname ) - 一种返回模块源的抽象方法。它使用通用换行符作为文本字符串返回,将所有已识别的行分隔符转换为
"\n"
字符。返回None
如果没有可用的源(例如内置模块)。如果加载程序找不到指定的模块,则ImportError
举起更改版本3.4:引发
ImportError
而不是NotImplementedError
.
is_package
(fullname)- 如果模块是包,则返回true值的抽象方法,否则返回false值。
ImportError
如果装载机找不到模块版本3.4更改:提高
ImportError
而不是NotImplementedError
.
- static
source_to_code
(data, path=”<string>”) - 从Python源码创建一个代码对象.
data参数可以是
compile()
functionsupports(即字符串或字节)。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()
instead.
- class
importlib.abc.
ExecutionLoader
- 继承自
InspectLoader
在实现时,它可以帮助模块作为脚本执行。ABC代表一个可选的 PEP 302 protocol.- abstractmethod
get_filename
(fullname) - 一个抽象方法,它将返回值
__file__
对于指定的模块。如果没有路径,则ImportError
被抬起如果源代码可用,则该方法应返回源文件的路径,无论是否使用字节码加载模块.
更改版本3.4:引发
ImportError
代替NotImplementedError
.
- abstractmethod
- class
importlib.abc.
FileLoader
(fullname, path) - 一个继承自
ResourceLoader
和ExecutionLoader
,提供ResourceLoader.get_data()
和ExecutionLoader.get_filename()
.fullnameargument是加载器要处理的模块的完全解析名称。path参数是模块文件的路径.
新版本3.3.
name
- 加载器可以处理的模块名称.
path
- 对模块文件的路径.
load_module
(fullname)- Calls super’s
load_module()
.从版本3.4开始不推荐使用:使用
Loader.exec_module()
代替
- abstractmethod
get_filename
// (fullname) - 返回
path
.
- abstractmethod
get_data
(path) - 读取path作为二进制文件并从中返回字节.
- class
importlib.abc.
SourceLoader
- 用于实现源(以及可选的字节码)文件加载的抽象基类。该类继承自
ResourceLoader
和ExecutionLoader
,需要执行:ResourceLoader.get_data()
-
ExecutionLoader.get_filename()
- 应该只返回源文件的路径;不支持无源加载.
此类定义的抽象方法是添加可选的字节码文件支持。没有实现这些可选方法(或导致它们使用
NotImplementedError
)会导致加载器只能使用源代码。实现这些方法允许带有源and字节码文件的加载器。它不允许sourceless加载只提供字节码的地方。字节码文件是通过删除Python编译器的解析步骤来加速加载的优化,因此不会暴露字节码特定的API .path_stats
(path)- 可选摘要返回
dict
包含有关指定路径的元数据的方法。支持的字典键是:"mtime"
(强制):表示源代码修改时间的整数或浮点数;"size"
(可选):源代码的字节大小.
忽略字典中的任何其他键,以允许将来扩展。如果路径无法处理,则
OSError
被抬起新版本3.3.
更改版本3.4:提升
OSError
而不是NotImplementedError
.
path_mtime
(path)- 可选的抽象方法,返回指定的修改时间path.
自版本3.3以后删除:这个方法不赞成使用
path_stats()
。你没有实现它,但它仍然可用于兼容性目的。如果路径无法处理则抬起OSError
在版本3.4:中改为
OSError
而不是NotImplementedError
.
set_data
(path, data)- 可选的抽象方法,将指定的字节写入文件路径。任何不存在的中间目录都是自动创建的.
由于路径是只读的(
errno.EACCES
/PermissionError
),写入路径失败时,不要传播theexception.在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__
的文件,当文件扩展名被移除时,确定该模块为和模块名称本身不以__init__
.
importlib.resources
– 资源
源代码:LIB /导入库/ resources.py
版本3.7.
该模块利用Python的导入系统提供对resources内packages。如果您可以导入包,则可以访问该包中的资源。可以以二进制ortext模式打开或读取资源.
资源大致类似于目录中的文件,但重要的是要记住这只是一个比喻。资源和包不要必须作为文件系统上的物理文件和目录存在.
注意
此模块提供类似于pkg_resources BasicResource Access的功能,但不包含该程序包的性能开销。这使得包中的阅读资源更容易,更稳定,更一致的语义.
该模块的独立后端提供了更多信息,使用importlib.resources并从pkg_resources迁移到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.
open_binary
(package, resource)- 打开二进制读取resource package.
package是一个符合
Package
要求的名称或模块对象。resource是打开的资源的名称package;它可能不包含路径分隔符,也可能没有子资源(即它不能是目录)。这个函数返回一个typing.BinaryIO
实例,一个二进制I / O流可供阅读
importlib.resources.
open_text
// (package, resource, encoding=”utf-8″, errors=”strict”)- 打开resource内的package阅读文本。默认情况下,打开资源以读取为UTF-8.
package是符合
Package
要求的名称或模块对象。resource是openwithin package的资源名称;它可能不包含路径分隔符,也可能没有子资源(即它不能是目录)。encoding和errors具有与内置相同的含义open()
.此函数返回一个
typing.TextIO
实例,一个文本I / O流打开读取
importlib.resources.
read_binary
// (package, resource)- 在resource中读取并返回package的内容为
bytes
.package是符合
Package
要求的名称或模块对象。resource是openwithin package的资源名称;它可能不包含路径分隔符,也可能没有子资源(即它不能是目录)。此函数返回资源的内容为bytes
.
importlib.resources.
read_text
(package, resource, encoding=”utf-8″, errors=”strict”)- 读取并返回resource内的package的内容为
str
。默认情况下,内容读取为严格UTF-8.package是符合
Package
要求的名称或模块对象。resource是openwithin package的资源名称;它可能不包含路径分隔符,也可能没有子资源(即它不能是目录)。encoding和errors与内置open()
具有相同的含义。该函数返回资源的内容为str
.
importlib.resources.
path
(package, resource)- 返回resource的路径作为实际的文件系统路径。该函数返回一个上下文管理器,用于
with
语句。上下文管理器提供一个pathlib.Path
object.退出上下文管理器会清除在需要从例如资源中提取资源时创建的任何临时文件。一个zip文件.
package是一个符合
Package
要求的名称或模块对象。resource是openwithin package的资源名称;它可能不包含路径分隔符,也可能没有子资源(即它不能是目录).
importlib.resources.
is_resource
(package, name)- 返回
True
如果包中有一个名为name的资源,否则False
。记住目录是not资源!package是一个符合Package
要求的名称或模块对象.
importlib.resources.
contents
(package)- 在包中的命名项上返回一个iterable。iterable返回
str
资源(例如文件)和非资源(例如目录)。iterable不会递归到子目录中.package是一个符合
Package
requirements.
importlib.machinery
的名称或模块对象 – 进口商和路径钩子
源代码: Lib / importlib / machinery.py
这个模块包含各种帮助import
查找和加载模块的对象.
importlib.machinery.
SOURCE_SUFFIXES
- 表示sourcemodules的已识别文件后缀的字符串列表.
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
- 表示已识别文件后缀的字符串列表forextension modules.
新版本3.3.
importlib.machinery.
all_suffixes
()- 返回表示标准导入机制识别的所有文件后缀格式模块的字符串组合列表。这对于代码来说只是需要知道文件系统路径是否潜在地引用模块而不需要有关模块类型的任何细节(例如,
inspect.getmodulename()
).3.3版本中的新功能
- class
importlib.machinery.
BuiltinImporter
- 一个进口商用于内置模块。所有已知的内置模块都列在
sys.builtin_module_names
。这个类实现了importlib.abc.MetaPathFinder
和importlib.abc.InspectLoader
ABCs.此类只定义了类方法,以减少实例化的需要.
在版本3.5中更改:作为…的一部分 PEP 489 ,内置进口商现在实施
Loader.create_module()
和Loader.exec_module()
- class
importlib.machinery.
FrozenImporter
- 一个进口商用于冷冻模块。这个类实现了
importlib.abc.MetaPathFinder
和importlib.abc.InspectLoader
ABCs.此类只定义了类方法,以减少实例化的需要.
- class
importlib.machinery.
WindowsRegistryFinder
- 发现者对于在Windows注册表中声明的模块。这个类实现了
importlib.abc.MetaPathFinder
ABC.这个类只定义了类方法,以减少实例化的需要.
新版本3.3.
从版本3.6开始不推荐使用:使用
site
而是配置。未来版本的Python默认情况下不能启用此查找器.
- class
importlib.machinery.
PathFinder
- 一个 发现者为
sys.path
和包__path__
这个类实现了importlib.abc.MetaPathFinder
ABC.这个类只定义了类方法,以减少实例化的需要.
- classmethod
find_spec
(fullname, path=None, target=None ) - 试图找到spec 对于fullname在
sys.path
指定的模块,或ifdefined,在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
aredeleted .更改版本3.7:的参赛作品
None
在sys.path_importer_cache
被删除了
版本3.4更改:在
sys.path_hooks
与当前工作目录""
(即空字符串). - classmethod
- class
importlib.machinery.
FileFinder
(path, *loader_details) importlib.abc.PathEntryFinder
的具体实现是文件系统的结果.path参数是其中的目录寻找者负责搜索
loader_details参数是一个可变数量的2项元组,每个元组包含一个加载器和一个加载器识别的文件后缀序列。加载器应该是callables,接受模块名称的两个参数和找到的文件的路径.
finder将根据需要缓存目录内容,为每个模块搜索进行stat调用,以验证缓存是否过时。因为cachestaleness依赖于操作系统的文件系统状态信息的粒度,所以存在搜索模块,创建新文件,然后搜索新文件所代表的模块的潜在竞争条件。如果操作发生得足够快以适应stat调用的粒度,则模块搜索将失败。防止这种情况发生,当你动态创建一个模块时,一定要调用
importlib.invalidate_caches()
.版本3.3中的新功能.
path
- 查找器搜索的路径.
find_spec
(fullname, target=None)- 尝试在fullname中找到处理
path
.版本3.4.
find_loader
(fullname)- 试图找到装载机来处理fullname内
path
.
invalidate_caches
()- 清除内部缓存.
- classmethod
path_hook
(*loader_details) - 一个类方法,它返回一个闭包用于
sys.path_hooks
。一个FileFinder
的实例由闭包使用直接给出闭包的path参数返回,loader_detailsindirectly.如果闭包的参数不是现有目录,
ImportError
被养了
- class
importlib.machinery.
SourceFileLoader
(fullname, path) - 的具体实现
importlib.abc.SourceLoader
bysubclassingimportlib.abc.FileLoader
并提供其他方法的一些具体实现.新版本3.3.
name
- 这个加载器将处理的模块的名称.
path
- 源文件的路径.
is_package
(fullname)- 如果
path
似乎是一个包装,则返回true.
path_stats
(path)importlib.abc.SourceLoader.path_stats()
.
set_data
的具体实施(path, data)importlib.abc.SourceLoader.set_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
可以导入字节码文件(即不存在源代码文件).请注意,直接使用字节码文件(因此不是源代码文件)会阻止所有Pythonimplementations或更新字节码格式的新版本Python使用模块.
3.3版本中的新功能.
name
- 加载器将处理的模块的名称.
path
- 字节码文件的路径.
is_package
(fullname )- 根据
path
.
get_code
(fullname)- 返回从
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
forextension modules的具体实现.fullnameargument指定加载器要支持的模块的名称。pathargument是扩展模块文件的路径.
3.3版本中的新功能
name
- 装载机支持的模块名称.
path
- 路径到扩展模块.
create_module
(spec)- 按照给定的规格创建模块对象 PEP 489 .
版本3.5中的新功能
exec_module
(module)- 按照PEP 489 .
版本3.5中的新功能
is_package
(fullname)- 返回
True
如果文件路径指向一个包的__init__
模块基于EXTENSION_SUFFIXES
.
get_code
(fullname)- 返回
None
因为扩展模块缺少代码对象
get_source
(fullname)- 回复
None
因为扩展模块没有源代码.
get_filename
(fullname)- Returns
path
.版本3.4.
- 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
.版本3.4.
name
(
__name__
)一个字符串,用于模块的完全限定名称.
loader
(
__loader__
)用于加载的加载程序。对于命名空间包,这应该设置为
None
.origin
(
__file__
)加载模块的地方的名称,例如“builtin”内置模块和从source加载的模块的文件名。应该设置“origin”,但它可能是
None
(默认值)表示它未指定(例如,对于命名空间包).submodule_search_locations
(
__path__
)在哪里可以找到子模块的字符串列表(如果是包)(
None
除此以外)。loader_state
在加载期间使用的额外模块特定数据的容器(或
None
).cached
(
__cached__
)应该存储编译模块的字符串(或
None
).parent
(
__package__
)(Read-only)模块属于子模块的包的完全限定名称(或
None
).has_location
Boolean指示模块的“origin”属性是否指向可加载位置.
importlib.util
– 导入程序的实用程序代码
来源code: Lib / importlib / util.py
这个模块包含有助于构造 importer的各种对象.
importlib.util.
MAGIC_NUMBER
- 代表的字节字节码版本号。如果您需要有关加载/写入字节码的帮助,请考虑
importlib.abc.SourceLoader
.版本3.4中的新功能
importlib.util.
cache_from_source
// (path, debug_override=None, *, optimization=None)- 返回 PEP3147 / 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
将被提出。)optimization参数用于指定thebytecode文件的优化级别。空字符串表示没有优化,所以
/foo/bar/baz.py
带optimization对""
将导致/foo/bar/__pycache__/baz.cpython-32.pyc
.None
使用interpter的优化级别。使用任何其他值的字符串表示,所以/foo/bar/baz.py
与 optimization的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.
在版本3.5中更改:添加了optimization参数和debug_override参数已被弃用.
版本3.6更改:接受路径对象.
importlib.util.
source_from_cache
(path)- 鉴于 path到PEP 3147 文件名,返回关联的源代码文件路径。例如,如果path是
/foo/bar/__pycache__/baz.cpython-32.pyc
返回的路径是/foo/bar/baz.py
. path不存在,但如果不符合PEP 3147 要么 PEP 488 格式,ValueError
被提出来。如果sys.implementation.cache_tag
未定义,则NotImplementedError
被抬起.新版本3.4.
更改版本3.6:接受一个路径对象.
importlib.util.
decode_source
(source_bytes)- 解码代表源代码的给定字节,并将其作为带有通用换行符的字符串返回(根据
importlib.abc.InspectLoader.get_source()
)的要求.版本3.4.
importlib.util.
resolve_name
(name, package)- 将相对模块名称解析为绝对名称.
如果名称没有前导点,那么名称是简单回来了。这可以用于
importlib.util.resolve_name("sys", __package__)
没有做麻烦,看是否需要包参数.ValueError
如果名称是一个相对模块name butpackage是一个假值(例如None
或空字符串).ValueError
还提出一个相对名称将逃脱其包装(例如从..bacon
包中请求spam
).版本3.3.
importlib.util.
find_spec
(name, package=None)- 找到 spec 对于模块,可选地相对于指定的包名称。如果模块在
sys.modules
中,则返回sys.modules[name].__spec__
(除非规格是None
或未设置,在这种情况下ValueError
被提出。)否则使用sys.meta_path
进行搜索。None
如果没有找到规格则返回.如果名称用于子模块(包含一个点),父模块将自动导入.
名称和包和
import_module()
.版本3.4.
更改版本3.7:提高
ModuleNotFoundError
代替AttributeError
如果包实际上不是一个包(即没有__path__
属性)。
importlib.util.
module_from_spec
(spec)- 基于符合规范和
spec.loader.create_module
.如果
spec.loader.create_module
不回来None
,那么任何预先存在的属性都不会被重置。也没有AttributeError
如果在访问符合规范或在模块上设置属性.此函数优于使用
types.ModuleType
创建新模块 spec 用于在模块上设置尽可能多的导入控制属性.3.5版本中的新版本
@
importlib.util.
module_for_loader
- //A 装饰者为
importlib.abc.Loader.load_module()
处理选择要加载的正确模块对象。预期装饰方法有一个带有两个位置参数的callignature(例如load_module(self, module)
)第二个参数将是加载器使用的模块 object 。请注意,由于两个参数的假设,装饰器将无法处理静态方法.装饰的方法将把名称加载到加载器的预期模块中。如果在
sys.modules
然后构建一个新的。无论模块来自哪里,__loader__
设置为自和__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 装饰为
importlib.abc.Loader.load_module()
设置__loader__
返回模块的属性。如果已设置该属性,则装饰器不执行任何操作。假设包裹方法的第一个位置参数(即self
)是__loader__
应该设置为更改版本3.4:设置
__loader__
如果设置为None
,就好像属性是notexist.从版本3.4开始不推荐使用:进口机械自动处理这个.
@
importlib.util.
set_package
- A 装饰器为
importlib.abc.Loader.load_module()
在返回的模块上设置__package__
属性。如果设置了__package__
并且其值不是None
它不会改变.自版本3.4:自动进口机器自动处理.
importlib.util.
spec_from_loader
(name, loader, *, origin=None, is_package=None)- 创建
ModuleSpec
基于加载器的实例。参数与forModuleSpec的含义相同。该函数使用 loader API,如InspectLoader.is_package()
,填写规格中的任何缺失信息版本3.4.
importlib.util.
spec_from_file_location
(name, location, *, loader=None, submodule_search_locations=None)- 用于创建
ModuleSpec
基于文件路径的实例。缺少的信息将通过使用加载器API填充在specpec上,并暗示模块将基于文件.新版本3.4.
版本3.6更改:接受路径对象.
importlib.util.
source_hash
(source_bytes)- 返回source_bytes作为字节。基于哈希的
.pyc
文件嵌入source_hash()
在theheader中对应源文件的内容在版本3.7.
- class
importlib.util.
LazyLoader
(loader) - 一个推迟模块加载程序执行的类,直到模块有一个属性访问.
这个班 只要适用于定义
exec_module()
因为需要控制模块使用的模块类型。出于同样的原因,加载器的create_module()
方法必须返回None
或者其类型为__class__
属性可以随着 slot 的使用而变异。最后,替换对象的模块放在sys.modules
无法正常工作,因为没有办法在整个翻译过程中安全地放置模块引用;如果检测到这样的替换,则会引发ValueError
.注意
对于启动时间至关重要的项目,如果从未使用过,那么这个类允许潜在地最小化加载模块的成本。对于启动时间不是必需的项目,那么使用这个类是严重由于在加载过程中产生的错误消息而被劝阻并因此发生在上下文之外。
版本3.5中的新功能
版本3.6更改:开始打电话
create_module()
,删除importlib.machinery.BuiltinImporter
和importlib.machinery.ExtensionFileLoader
.- classmethod
factory
(loader) - 一个静态方法,它返回一个用于创建延迟加载器的callable。这意味着用于装载程序按类传递而不是实例的情况.
suffixes = importlib.machinery.SOURCE_SUFFIXES loader = importlib.machinery.SourceFileLoader lazy_loader = importlib.util.LazyLoader.factory(loader) finder = importlib.machinery.FileFinder(path, (lazy_loader, suffixes))
- classmethod
示例
以编程方式导入
要以编程方式导入模块,请使用importlib.import_module()
.
import importlib
itertools = importlib.import_module('itertools')
检查是否可以导入模块
如果您需要确定是否可以导入模块而不实际执行导入,那么您应该使用importlib.util.find_spec()
.
import importlib.util
import sys
# For illustrative purposes.
name = 'itertools'
spec = importlib.util.find_spec(name)
if spec is None:
print("can't find the itertools module")
else:
# If you chose to perform the actual import ...
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
# Adding the module to sys.modules is optional.
sys.modules[name] = 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)
spec.loader.exec_module(module)
# Optional; only necessary if you want to be able to import the module
# by name later.
sys.modules[module_name] = module
设置导入器
对于导入的深度自定义,通常需要实现进口商。这意味着同时管理 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))
近似importlib.import_module()
导入本身是在Python代码中实现的,因此可以通过importlib公开大多数导入机制。以下帮助通过提供importlib.import_module()
的近似实现来说明importlib公开的各种API(对于importlib用法使用Python 3.4和更新版本,对于代码的其他部分使用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)
spec.loader.exec_module(module)
sys.modules[absolute_name] = module
if path is not None:
setattr(parent_module, child_name, module)
return module
评论被关闭。