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

相關文章
相關標籤/搜索