千锋教育-做有情怀、有良心、有品质的职业教育机构

400-811-9990
手机站
千锋教育

千锋学习站 | 随时随地免费学

千锋教育

扫一扫进入千锋手机站

领取全套视频
千锋教育

关注千锋学习站小程序
随时随地免费学习课程

上海
  • 北京
  • 郑州
  • 武汉
  • 成都
  • 西安
  • 沈阳
  • 广州
  • 南京
  • 深圳
  • 大连
  • 青岛
  • 杭州
  • 重庆
当前位置:重庆千锋IT培训  >  技术干货  >  Python 的 import 机制

Python 的 import 机制

来源:千锋教育
发布人:xqq
时间: 2023-11-12 13:26:35

1.1什么是import机制?

通常来讲,在一段Python代码中去执行引用另一个模块中的代码,就需要使用Python的import机制。import语句是触发import机制最常用的手段,但并不是唯一手段。

importlib.import_module和__import__函数也可以用来引入其他模块的代码。

1.2import是如何执行的?

import语句会执行两步操作:

搜索需要引入的模块

将模块的名字做为变量绑定到局部变量中

搜索步骤实际上是通过__import__函数完成的,而其返回值则会作为变量被绑定到局部变量中。下面我们会详细聊到__import__函数是如果运作的。

二、import机制概览

下图是import机制的概览图。不难看出,当import机制被触发时,Python首先会去sys.modules中查找该模块是否已经被引入过,如果该模块已经被引入了,就直接调用它,否则再进行下一步。这里sys.modules可以看做是一个缓存容器。值得注意的是,如果sys.modules中对应的值是None那么就会抛出一个ModuleNotFoundError异常。下面是一个简单的实验:

In[1]:importsys

In[2]:sys.modules['os']=None

In[3]:importos

---------------------------------------------------------------------------

ModuleNotFoundErrorTraceback(mostrecentcalllast)

in

---->1importos

ModuleNotFoundError:importofoshalted;Noneinsys.modules

如果在sys.modules找到了对应的module,并且这个import是由import语句触发的,那么下一步将对把对应的变量绑定到局部变量中。

如果没有发现任何缓存,那么系统将进行一个全新的import过程。在这个过程中Python将遍历sys.meta_path来寻找是否有符合条件的元路径查找器(metapathfinder)。sys.meta_path是一个存放元路径查找器的列表。它有三个默认的查找器:

内置模块查找器

冻结模块(frozenmodule)查找器

基于路径的模块查找器。

In[1]:importsys

In[2]:sys.meta_path

Out[2]:

[_frozen_importlib.BuiltinImporter,

_frozen_importlib.FrozenImporter,

_frozen_importlib_external.PathFinder]

查找器的find_spec方法决定了该查找器是否能处理要引入的模块并返回一个ModeuleSpec对象,这个对象包含了用来加载这个模块的相关信息。如果没有合适的ModuleSpec对象返回,那么系统将查看sys.meta_path的下一个元路径查找器。如果遍历sys.meta_path都没有找到合适的元路径查找器,将抛出ModuleNotFoundError。引入一个不存在的模块就会发生这种情况,因为sys.meta_path中所有的查找器都无法处理这种情况:

In[1]:importnosuchmodule

---------------------------------------------------------------------------

ModuleNotFoundErrorTraceback(mostrecentcalllast)

in

---->1importnosuchmodule

ModuleNotFoundError:Nomodulenamed'nosuchmodule'

但是,如果这个手动添加一个可以处理这个模块的查找器,那么它也是可以被引入的:

In[1]:importsys

...:

...:fromimportlib.abcimportMetaPathFinder

...:fromimportlib.machineryimportModuleSpec

...:

...:classNoSuchModuleFinder(MetaPathFinder):

...:deffind_spec(self,fullname,path,target=None):

...:returnModuleSpec('nosuchmodule',None)

...:

...:#don'tdothisinyourscript

...:sys.meta_path=[NoSuchModuleFinder()]

...:

...:importnosuchmodule

---------------------------------------------------------------------------

ImportErrorTraceback(mostrecentcalllast)

in

11sys.meta_path=[NoSuchModuleFinder()]

12

--->13importnosuchmodule

ImportError:missingloader

可以看到,当我们告诉系统如何去find_spec的时候,是不会抛出ModuleNotFound异常的。但是要成功加载一个模块,还需要加载器loader。

加载器是ModuleSpec对象的一个属性,它决定了如何加载和执行一个模块。如果说ModuleSpec对象是“师父领进门”的话,那么加载器就是“修行在个人”了。在加载器中,你完全可以决定如何来加载以及执行一个模块。这里的决定,不仅仅是加载和执行模块本身,你甚至可以修改一个模块:

In[1]:importsys

...:fromtypesimportModuleType

...:fromimportlib.machineryimportModuleSpec

...:fromimportlib.abcimportMetaPathFinder,Loader

...:

...:classModule(ModuleType):

...:def__init__(self,name):

...:self.x=1

...:self.name=name

...:

...:classExampleLoader(Loader):

...:defcreate_module(self,spec):

...:returnModule(spec.name)

...:

...:defexec_module(self,module):

...:module.y=2

...:

...:classExampleFinder(MetaPathFinder):

...:deffind_spec(self,fullname,path,target=None):

...:returnModuleSpec('module',ExampleLoader())

...:

...:sys.meta_path=[ExampleFinder()]

In[2]:importmodule

In[3]:module

Out[3]:)>

In[4]:module.x

Out[4]:1

In[5]:module.y

Out[5]:2

从上面的例子可以看到,一个加载器通常有两个重要的方法create_module和exec_module需要实现。如果实现了exec_module方法,那么create_module则是必须的。如果这个import机制是由import语句发起的,那么create_module方法返回的模块对象对应的变量将会被绑定到当前的局部变量中。如果一个模块因此成功被加载了,那么它将被缓存到sys.modules。如果这个模块再次被加载,那么sys.modules的缓存将会被直接引用。

以上内容为大家介绍了Python的import机制,希望对大家有所帮助,如果想要了解更多Python相关知识,请关注IT培训机构:千锋教育。

声明:本站稿件版权均属千锋教育所有,未经许可不得擅自转载。

猜你喜欢LIKE

python异步中selectors的使用

2023-11-14

python交集有什么作用?

2023-11-14

pythonfloat函数怎么用

2023-11-14

最新文章NEW

pythonreversed的反向迭代

2023-11-14

python匿名函数的命名规则

2023-11-14

python使用协程的缺点

2023-11-14

相关推荐HOT

更多>>

快速通道 更多>>

最新开班信息 更多>>

网友热搜 更多>>