python提供了importlib包作為標準庫的一部分。目的就是提供python中import語句的實現(以及__import__
函式)。另外,importlib允許程式設計師建立他們自定義的物件,可用於引入過程(也稱為importer)。
什麼是imp?
另外有乙個叫做imp的模組,它提供給python import語句機制的介面。這個模組在python 3.4中被否決,目的就是為了只使用importlib。
這個模組有些複雜,因此我們在這篇博文中主要討論以下幾個主題:
importlib模組支援傳入字串來引入乙個模組。我們建立兩個簡單的模組來驗證這個功能。我們將會給予兩個模組相同的介面,讓它們列印名字以便我們能夠區分它們。建立兩個模組,分別為foo.py和bar.py,**如下所示,
def main():
print(__name__)12
現在我們使用importlib來引入它們。讓我們看看這段**如何去做的。確保你已經把這段**放在與上面建立的兩個模組相同的目錄下。
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.main()1234567891011
在這段**中,我們手動引入importlib模組,並建立乙個簡單的函式dynamic_import。這個函式所做的就是呼叫importlib模組中的import_module函式,入參就是我們傳入的字串,然後返**用結果。在**段的下面,我們呼叫每個模組的main方法,將會列印出每個模組的名稱。
在你的**中,你可能不會大量這樣做。當你只有乙個字串時,如果你想引入這個模組,importlib就允許你可以這麼做。
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))1234567891011121314151617181920212223242526
這裡我們引入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通過模組名和檔案路徑來引入乙個模組。示例如下所示,
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 has the following methods:"
print(msg.format(module_name = module_name ,methods = dir(module)))
if __name__ == "__main__":
import logging
import_source(logging)1234567891011121314151617
上述**中,我們實際引入了logging模組,並將它傳入到import_source函式。在這個函式中,我們首先獲取到模組的實際路徑和名稱。然後我們將這些資訊傳入到util的spec_from_file_location函式中,這個將會返回模組的說明。一旦我們獲取到模組的說明,我們就可以使用與2.2節相同的importlib機制來實際引入模組。
現在讓我們來看乙個精巧的第三方庫,python的__import__()
函式直接引入github中的包。
pip install import_from_github_com1
這個包使用了pep 302中新的引入鉤子,允許你可以從github上引入包。這個包實際做的就是安裝這個包並將它新增到本地。你需要python 3.2或者更高的版本,git和pip才能使用這個包。
一旦這些已經安裝,你可以在python shell中輸入如下命令,
>>> from github_com.zzzeek import sqlalchemy
collecting git+
cloning to /tmp/pip-acfv7t06-build
installing collected packages: sqlalchemy
running setup.py install for sqlalchemy ... done
successfully installed sqlalchemy-1.1.0b1.dev0
>>> locals()
123456789101112
你如果看了import_from_github_com的原始碼,你將會注意到它並沒有使用importlib。實際上,它使用了pip來安裝那些沒有安裝的包,然後使用python的import()函式來引入新安裝的模組。這段**非常值得學習。 Python中標準型別的區別
python中有5種基本型別 1 number 數字 2 string 字串 3 list 列表 4 tuple 元組 5 dictionary 字典 numbers用於儲存數值,資料型別不可變,因此這也表明改變量字的資料型別會重新分配乙個新的物件。numbers的型別有int long float...
Python標準模組 sys
import syspath sys.path是模組搜尋路徑。python在程式啟動時進行配置,自動將頂級檔案的主目錄 任何pythonpath目錄 標準庫目錄 pth檔案中目錄合併。from sys import path舉例 如果想要呼叫另乙個資料夾中的某個函式,比如 path dir funf...
Python標準模組 functools
functools,用於高階函式 指那些作用於函式或者返回其它函式的函式,通常只要是可以被當做函式呼叫的物件就是這個模組的目標。在python 2.7 中具備如下方法,cmp to key,將乙個比較函式轉換關鍵字函式 partial,針對函式起作用,並且是部分的 reduce,與python內建的...