You are here:  Home » Python » importlib- 执行-Importing Modules(Python教程)(参考资料)

importlib– 实施 import

版本3.1.

源代码:LIB /导入库/ __ init__.py


介绍

的目的importlib包装是双重的。一个是在Python源代码中提供import语句的实现(因此,扩展名为__import__()函数)。这提供了import它可以移植到任何Python解释器。这也提供了一种比Python以外的编程语言更容易理解的实现.

二,实现import的组件暴露在这个包中,使用户更容易创建自己的自定义对象(统称为导入器)参与导入过程.

参见

导入声明
import声明的语言参考
包装规格
包的原始规格。自撰写本文档以来,一些语义已发生变化(例如,基于重定向Nonesys.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和其他关键模块不推荐。在许多情况下,扩展模块不是设计为不止一次初始化,并且可能在重新加载时以任意方式失败.

如果一个模块使用fromimport …从另一个模块导入对象,则为另一个模块调用reload()不会重新定义从它导入的对象 – 解决这个问题的方法之一就是 -执行from声明,另一种是使用import和限定名称(module.name)代替

如果模块实例化类的实例,则重新加载定义类的模块不会影响实例的方法定义 – 他们继续使用旧的类定义。派生类也是如此.

版本3.4.

更改版本3.7:ModuleNotFoundError重新加载模块时出现错误ModuleSpec.

 

importlib.abc– 与导入相关的抽象基类

源代码:LIB /导入库/ abc.py


importlib.abcmodule包含import。还提供了核心抽象基类的一些子类来帮助实现核心ABC .

ABC等级:

object
 +-- Finder (deprecated)
 |    +-- MetaPathFinder
 |    +-- PathEntryFinder
 +-- Loader
      +-- ResourceLoader --------+
      +-- InspectLoader          |
           +-- ExecutionLoader --+
                                 +-- FileLoader
                                 +-- SourceLoader
class importlib.abc.Finder
表示发现者.

从版本3.3开始不推荐使用:使用 MetaPathFinder要么 PathEntryFinder代替。

abstractmethod find_modulefullname, path=None
找一个装载机对于指定的模块。最初在PEP 302 ,这个方法适用于sys.meta_path并在基于路径的导入子系统中

版本3.4更改:调用时返回None而不是引发NotImplementedError.

class importlib.abc.MetaPathFinder
表示元路径查找器的抽象基类。为了兼容性,这是版本3.3中的Finder.

的新类.

find_spec (fullname, path, target=None)
一种抽象方法,用于查找指定模块的 spec 。如果这是顶级导入,pathNone。否则,这是搜索子包ormodule和path将是来自theparent包的__path__的值。如果找不到规格,则返回None。传入时,target是一个模块对象,查找器可以用来对返回的规格进行更有根据的猜测.

新版本3.4.

find_module (fullname, path )
找到装载机的传统方法对于指定的模块。如果这是顶级导入,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
表示路径条目查找器的抽象基类。虽然与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来表示加载程序不是命名空间包的一部分。如果loaderNoneportion是空列表然后没有找到命名空间包的加载器或位置(即没有找到模块的任何东西).

如果find_spec()定义然后提供向后兼容的功能.

版本3.4更改:返回(None, [])而不是提高NotImplementedError。使用find_spec()什么时候提供功能

从版本3.4开始不推荐使用:使用 find_spec()代替。

find_modulefullname
的具体实现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_resourceresource
返回一个打开的文件般的对象对于resource.

的二进制读取如果找不到资源,FileNotFoundError israised.

abstractmethod resource_path(resource)
返回文件系统路径去resource.

如果资源在文件系统上没有具体存在,则引发FileNotFoundError.

abstractmethod is_resourcename
返回True如果命名name被视为资源.FileNotFoundError如果name不存在。
abstractmethod contents
返回可迭代包裹内容的字符串。请注意,迭代器返回的所有名称都不需要是实际资源,例如:返回is_resource()会是假的.

允许返回非资源名称是为了允许包装及其资源的存储方式是先验已知的,并且非资源名称是有用的。例如,允许返回子目录名称,以便在知道包时和资源存储在文件系统上,然后这些子目录名可以直接使用.

抽象方法返回一个无项目的迭代.

class importlib.abc.ResourceLoader
加载器的抽象基类实现了可选的 PEP 302 从storageback-end.

从版本3.7开始不推荐使用:这个ABC被弃用,支持通过importlib.abc.ResourceReader.

abstractmethod get_datapath
返回字节的抽象方法数据位于path.Loaders具有类似文件的存储后端,允许存储任意数据库,实现这种抽象方法,直接访问存储的数据。OSError如果找不到path就会被提出来。path应该使用模块的__file__属性或包中的项来构造__path__.

在版本3.4中更改:引发OSError而不是NotImplementedError.

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_packagefullname
如果模块是包,则返回true值的抽象方法,否则返回false值。ImportError如果装载机找不到模块

版本3.4更改:提高ImportError而不是NotImplementedError.

static source_to_codedata, path=”<string>”
从Python源码创建一个代码对象.

data参数可以是compile() functionsupports(即字符串或字节)。path参数应该是源代码源自的“路径”,可以是抽象概念(例如zip文件中的位置).

使用后续代码对象,可以通过运行exec(code, module.__dict__).

版本3.4.

在版本3.5中更改:使方法静止

exec_modulemodule
实施 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.

class importlib.abc.FileLoaderfullname, path
一个继承自ResourceLoaderExecutionLoader,提供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_datapath
读取path作为二进制文件并从中返回字节.
class importlib.abc.SourceLoader
用于实现源(以及可选的字节码)文件加载的抽象基类。该类继承自ResourceLoaderExecutionLoader,需要执行:

  • 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_mtimepath
可选的抽象方法,返回指定的修改时间path.

自版本3.3以后删除:这个方法不赞成使用path_stats()。你没有实现它,但它仍然可用于兼容性目的。如果路径无法处理则抬起OSError

在版本3.4:中改为OSError而不是NotImplementedError.

set_datapath, data
可选的抽象方法,将指定的字节写入文件路径。任何不存在的中间目录都是自动创建的.

由于路径是只读的(errno.EACCES/PermissionError),写入路径失败时,不要传播theexception.

在3.4版本中更改:在调用时不再提升NotImplementedError.

get_code (fullname )
具体实现InspectLoader.get_code().
exec_modulemodule
具体实现Loader.exec_module().

新版本3.4.

load_module (fullname
具体实现Loader.load_module().

自版本3.4以后不推荐使用使用exec_module()而不是

get_sourcefullname)
InspectLoader.get_source().
is_package的具体实现(fullname
具体实现InspectLoader.is_package()。如果一个模块的文件路径(由ExecutionLoader.get_filename()提供)是一个名为__init__的文件,当文件扩展名被移除时,确定该模块为模块名称本身不以__init__.

 

importlib.resources– 资源

源代码:LIB /导入库/ resources.py


版本3.7.

该模块利用Python的导入系统提供对resourcespackages。如果您可以导入包,则可以访问该包中的资源。可以以二进制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的资源名称;它可能不包含路径分隔符,也可能没有子资源(即它不能是目录)。encodingerrors具有与内置相同的含义open().

此函数返回一个typing.TextIO实例,一个文本I / O流打开读取

importlib.resources.read_binary// (package, resource
resource中读取并返回package的内容为bytes.

package是符合Package要求的名称或模块对象。resource是openwithin package的资源名称;它可能不包含路径分隔符,也可能没有子资源(即它不能是目录)。此函数返回资源的内容为bytes.

importlib.resources.read_textpackage, resource, encoding=”utf-8″, errors=”strict”
读取并返回resource内的package的内容为str。默认情况下,内容读取为严格UTF-8.

package是符合Package要求的名称或模块对象。resource是openwithin package的资源名称;它可能不包含路径分隔符,也可能没有子资源(即它不能是目录)。encodingerrors与内置open()具有相同的含义。该函数返回资源的内容为str.

importlib.resources.pathpackage, resource
返回resource的路径作为实际的文件系统路径。该函数返回一个上下文管理器,用于with语句。上下文管理器提供一个pathlib.Path object.

退出上下文管理器会清除在需要从例如资源中提取资源时创建的任何临时文件。一个zip文件.

package是一个符合Package要求的名称或模块对象。resource是openwithin package的资源名称;它可能不包含路径分隔符,也可能没有子资源(即它不能是目录).

importlib.resources.is_resourcepackage, name
返回True如果包中有一个名为name的资源,否则False。记住目录是not资源!package是一个符合Package要求的名称或模块对象.
importlib.resources.contentspackage
在包中的命名项上返回一个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.MetaPathFinderimportlib.abc.InspectLoaderABCs.

此类只定义了类方法,以减少实例化的需要.

在版本3.5中更改:作为…的一部分 PEP 489 ,内置进口商现在实施Loader.create_module()Loader.exec_module()

class importlib.machinery.FrozenImporter
一个进口商用于冷冻模块。这个类实现了importlib.abc.MetaPathFinderimportlib.abc.InspectLoaderABCs.

此类只定义了类方法,以减少实例化的需要.

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 对于fullnamesys.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_modulefullname, 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:的参赛作品Nonesys.path_importer_cache被删除了

版本3.4更改:sys.path_hooks与当前工作目录""(即空字符串).

class importlib.machinery.FileFinderpath, *loader_details
importlib.abc.PathEntryFinder的具体实现是文件系统的结果.

path参数是其中的目录寻找者负责搜索

loader_details参数是一个可变数量的2项元组,每个元组包含一个加载器和一个加载器识别的文件后缀序列。加载器应该是callables,接受模块名称的两个参数和找到的文件的路径.

finder将根据需要缓存目录内容,为每个模块搜索进行stat调用,以验证缓存是否过时。因为cachestaleness依赖于操作系统的文件系统状态信息的粒度,所以存在搜索模块,创建新文件,然后搜索新文件所代表的模块的潜在竞争条件。如果操作发生得足够快以适应stat调用的粒度,则模块搜索将失败。防止这种情况发生,当你动态创建一个模块时,一定要调用importlib.invalidate_caches().

版本3.3中的新功能.

path
查找器搜索的路径.
find_specfullname, target=None
尝试在fullname中找到处理path.

版本3.4.

find_loaderfullname
试图找到装载机来处理fullnamepath.
invalidate_caches
清除内部缓存.
classmethod path_hook*loader_details
一个类方法,它返回一个闭包用于sys.path_hooks。一个FileFinder的实例由闭包使用直接给出闭包的path参数返回,loader_detailsindirectly.

如果闭包的参数不是现有目录,ImportError被养了

class importlib.machinery.SourceFileLoaderfullname, path
的具体实现importlib.abc.SourceLoaderbysubclassing importlib.abc.FileLoader并提供其他方法的一些具体实现.

新版本3.3.

name
这个加载器将处理的模块的名称.
path
源文件的路径.
is_packagefullname
如果path似乎是一个包装,则返回true.
path_stats (path)
importlib.abc.SourceLoader.path_stats().
set_data的具体实施(path, data
importlib.abc.SourceLoader.set_data().
load_modulename=None)的具体实现
具体实现importlib.abc.Loader.load_module()指定要加载的模块名称是可选的.

自版本3.6以后删除:使用importlib.abc.Loader.exec_module()代替

class importlib.machinery.SourcelessFileLoaderfullname, path
importlib.abc.FileLoader可以导入字节码文件(即不存在源代码文件).

请注意,直接使用字节码文件(因此不是源代码文件)会阻止所有Pythonimplementations或更新字节码格式的新版本Python使用模块.

3.3版本中的新功能.

name
加载器将处理的模块的名称.
path
字节码文件的路径.
is_package (fullname )
根据path.
get_codefullname
返回从namepath.
get_sourcefullname创建的
的代码对象返回None,因为当使用此加载器时,字节码文件没有源代码.
load_module (name=None)

importlib.abc.Loader.load_module()指定要加载的模块名称是可选的.

自版本3.6以后删除:使用importlib.abc.Loader.exec_module()代替

class importlib.machinery.ExtensionFileLoaderfullname, path
importlib.abc.ExecutionLoader forextension modules的具体实现.

fullnameargument指定加载器要支持的模块的名称。pathargument是扩展模块文件的路径.

3.3版本中的新功能

name
装载机支持的模块名称.
path
路径到扩展模块.
create_module (spec)
按照给定的规格创建模块对象 PEP 489 .

版本3.5中的新功能

exec_modulemodule
按照PEP 489 .

版本3.5中的新功能

is_packagefullname
返回True如果文件路径指向一个包的__init__模块基于EXTENSION_SUFFIXES.
get_codefullname
返回None因为扩展模块缺少代码对象
get_sourcefullname)
回复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.pyccpython-32字符串来自当前的魔术标记(参见get_tag();如果sys.implementation.cache_tag没有定义然后NotImplementedError将被提出。)

optimization参数用于指定thebytecode文件的优化级别。空字符串表示没有优化,所以/foo/bar/baz.pyoptimization""将导致/foo/bar/__pycache__/baz.cpython-32.pyc. None使用interpter的优化级别。使用任何其他值的字符串表示,所以/foo/bar/baz.pyoptimization2将导致/foo/bar/__pycache__/baz.cpython-32.opt-2.pyc的字节码路径。optimization的字符串表示只能是字母数字,否则ValueError被抬起

// debug_override参数已弃用,可用于覆盖__debug__的系统值。True值相当于将optimization设置为空字符串。一个False值是同样的资产optimization1。如果debug_override optimization不是None那么TypeError被抬起来

新版本3.4.

在版本3.5中更改:添加了optimization参数和debug_override参数已被弃用.

版本3.6更改:接受路径对象.

importlib.util.source_from_cachepath
鉴于 pathPEP 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_sourcesource_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_specspec
基于符合规范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_locationname, location, *, loader=None, submodule_search_locations=None
用于创建ModuleSpec基于文件路径的实例。缺少的信息将通过使用加载器API填充在specpec上,并暗示模块将基于文件.

新版本3.4.

版本3.6更改:接受路径对象.

importlib.util.source_hashsource_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.BuiltinImporterimportlib.machinery.ExtensionFileLoader.

classmethod factoryloader
一个静态方法,它返回一个用于创建延迟加载器的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))

 

示例

以编程方式导入

要以编程方式导入模块,请使用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

评论被关闭。