importlib模块

importlib模块

能够将字符串进行拆分python

重点掌握

import importlib
 mod = importlib.import_module('notify.email' )
 这个时候就是将notify.email 拆分红 from notify import email
 mod这个时候就等于email
 它能够点email内部的全部方法
 
 通常的使用
 cls=attr(mod,'Email')
 从mod模块内部获取Email类
 这个时候cls就是Eail类
 而后能够初始化
 obj=cls()获取对象
 用对象点取类中的方法等。

模块简介

Python提供了importlib包做为标准库的一部分。目的就是提供Python中import语句的实现(以及__import__函数)。另外,importlib容许程序员建立他们自定义的对象,可用于引入过程(也称为importer)。git

什么是imp?程序员

另外有一个叫作imp的模块,它提供给Python import语句机制的接口。这个模块在Python 3.4中被否决,目的就是为了只使用importlib。github

这个模块有些复杂,所以咱们在这篇博文中主要讨论如下几个主题:sql

•动态引入
•检查模块是否能够被引入
•引入源文件自身
•第三方模块 import_from_github_comshell

模块使用

2.1 动态引入函数

importlib模块支持传入字符串来引入一个模块。咱们建立两个简单的模块来验证这个功能。咱们将会给予两个模块相同的接口,让它们打印名字以便咱们可以区分它们。建立两个模块,分别为foo.py和bar.py,代码以下所示,学习

def main():
 print(__name__)

如今咱们使用importlib来引入它们。让咱们看看这段代码如何去作的。确保你已经把这段代码放在与上面建立的两个模块相同的目录下。ui

#importer.py
import importlib
 
def dynamic_import(module):
 return importlib.import_module(module)
 
if __name__ == "__main__":
 module = dynamic_import('foo')
 module.main()
 
 module_two = dynamic_import('bar')
 module_two()

在这段代码中,咱们手动引入importlib模块,并建立一个简单的函数dynamic_import。这个函数所作的就是调用importlib模块中的import_module函数,入参就是咱们传入的字符串,而后返回调用结果。在代码段的下面,咱们调用每一个模块的main方法,将会打印出每一个模块的名称。编码

在你的代码中,你可能不会大量这样作。当你只有一个字符串时,若是你想引入这个模块,importlib就容许你能够这么作。

模块引入检查

Python有一个编码规范就是EAPP:Easier to ask for forgiveness than permision。意思就是常常假设一些事情是存在的(例如,key在词典中),若是出错了,那么就捕获异常。你能够看 Python标准模块--import 文章中咱们尝试引入模块,当它不存在时,咱们就会捕获到ImportError。若是咱们想检查并观察一个模块是否能够引入而不是仅仅是猜想,该如何去作?你能够使用importlib。代码以下:

#coding:utf-8
 
import importlib.util
import importlib
 
def check_module(module_name):
 module_spec = importlib.util.find_spec(module_name)
 if module_spec is None:
 print("Module :{} not found".format(module_name))
 return None
 else:
 print("Module:{} can be imported!".format(module_name))
 return module_spec
  
def import_module_from_spec(module_spec):
 module = importlib.util.module_from_spec(module_spec)
 module_spec.loader.exec_module(module)
 return module
 
if __name__ == "__main__":
 module_spec = check_module("fake_module")
 module_spec = check_module("collections")
 if(module_spec):
 module = import_module_from_spec(module_spec)
 print(dir(module))

这里咱们引入importlib模块的子模块util。在check_module函数中,咱们调用find_spec函数来检查传入的字符串做为模块是否存在。首先,咱们传入一个假的名称,而后咱们传入一个Python模块的真实名称。若是你运行这段代码,你将会看到你传入一个没有安装的模块的名称,find_spec函数将会返回None,咱们的代码将会打印出这个模块没有找到。若是找到了,咱们就会返回模块的说明。

咱们能够获取到模块的说明,而后使用它来真正的引入模块。或者你能够将字符串传入到import_module函数中,正如咱们在2.1节中所学习到的同样。可是咱们已经学习到如何使用模块的说明。让咱们看一下上述代码中的import_module_from_spec函数。它接受由check_module函数返回的模块说明。咱们将其传入到module_from_spec函数,它将会返回引入的模块。Python的官方文档推荐,在引入模块后执行它,因此咱们下一步作的就是调用exec_module函数。最后咱们返回这个模块,而且运行Python的dir函数来确认这个咱们就是咱们所指望的。

从源文件中引入

在这一节中,我想说明importlib的子模块util还有另一个技巧。你能够使用util经过模块名和文件路径来引入一个模块。示例以下所示,

#coding:utf-8
 
import importlib.util
 
def import_source(module_name):
 module_file_path = module_name.__file__
 module_name = module_name.__name__
  
 module_spec = importlib.util.spec_from_file_location(module_name,module_file_path)
 module = importlib.util.module_from_spec(module_spec)
 module_spec.loader.exec_module(module)
 print(dir(module))
 
 msg = "The {module_name} module has the following methods:{methods}"
 print(msg.format(module_name = module_name,methods = dir(module)))
  
if __name__ == "__main__":
 import logging
 import_source(logging)

上述代码中,咱们实际引入了logging模块,并将它传入到import_source函数。在这个函数中,咱们首先获取到模块的实际路径和名称。而后咱们将这些信息传入到util的spec_from_file_location函数中,这个将会返回模块的说明。一旦咱们获取到模块的说明,咱们就能够使用与2.2节相同的importlib机制来实际引入模块。

如今让咱们来看一个精巧的第三方库,Python的__import__()函数直接引入github中的包。

import_from_github_com

这个精巧的包叫作import_from_github_com,它能够用于发现和下载github上的包。为了安装他,你须要作的就是按照以下命令使用pip,

pip install import_from_github_com

这个包使用了PEP 302中新的引入钩子,容许你能够从github上引入包。这个包实际作的就是安装这个包并将它添加到本地。你须要Python 3.2或者更高的版本,git和pip才能使用这个包。

一旦这些已经安装,你能够在Python shell中输入以下命令,

>>> from github_com.zzzeek import sqlalchemy
Collecting git+https://github.com/zzzeek/sqlalchemy
Cloning https://github.com/zzzeek/sqlalchemy to /tmp/pip-acfv7t06-build
Installing collected packages: SQLAlchemy
Running setup.py install for SQLAlchemy ... done
Successfully installed SQLAlchemy-1.1.0b1.dev0
>>> locals()
{'__builtins__': <module 'builtins' (built-in)>, '__spec__': None,
'__package__': None, '__doc__': None, '__name__': '__main__',
'sqlalchemy': <module 'sqlalchemy' from '/usr/local/lib/python3.5/site-packages/\
sqlalchemy/__init__.py'>,
'__loader__': <class '_frozen_importlib.BuiltinImporter'>}

你若是看了import_from_github_com的源码,你将会注意到它并无使用importlib。实际上,它使用了pip来安装那些没有安装的包,而后使用Python的__import__()函数来引入新安装的模块。这段代码很是值得学习。

总结

到这里,你已经了解到在你的代码中如何使用importlib和引入钩子。固然还有不少超出本文所覆盖的知识,若是你须要写一个自定义的引入器或者下载器,你须要花费不少时间来阅读官方文档和源码。

转载自:https://www.jb51.net/article/111282.htm

相关文章
相关标签/搜索