Python將importlib作為標(biāo)準(zhǔn)庫提供。它旨在提供Pythonimport語法和(__import__()函數(shù))的實現(xiàn)。另外,importlib提供了開發(fā)者可以創(chuàng)建自己的對象(即importer)來處理導(dǎo)入過程。 使用如下: 新建一個.py文件,resnet1 在新建一個train文件 介紹importlibPython將importlib作為標(biāo)準(zhǔn)庫提供。它旨在提供Pythonimport語法和(__import__()函數(shù))的實現(xiàn)。另外,importlib提供了開發(fā)者可以創(chuàng)建自己的對象(即importer)來處理導(dǎo)入過程。 那么imp呢?還有一個imp模塊提供了import語句接口,不過這個模塊在Python3.4已經(jīng)deprecated了。建議使用importlib來處理。 這個模塊比較復(fù)雜,文中我們主要探討如下主題:
我們先從動態(tài)導(dǎo)入開始。 動態(tài)導(dǎo)入importlib模塊支持傳遞字符串來導(dǎo)入模塊。我們先來創(chuàng)建一些簡單模塊一遍演示。我們在模塊里提供了相同接口,通過打印它們自身名字來區(qū)分。我們分別創(chuàng)建了foo.py和bar.py,代碼如下: def main(): print(__name__) 現(xiàn)在我們盡需要使用importlib導(dǎo)入它們。我們來看看代碼是如何實現(xiàn)的,確保該代碼在剛才創(chuàng)建的兩個文件的相同目錄下。 #importer
import importlib
def dynamic_import(module):
return importlib.import_module(module)
if __name__ == "__main__":
module = dynamic_import('foo')
module.main()
module2 = dynamic_import('bar')
module2.main()
這里我們導(dǎo)入importlib模塊,并創(chuàng)建了一個非常簡單的函數(shù)dynamic_import。這個函數(shù)直接就調(diào)用了importlib的import_module方法,并將要導(dǎo)入的模塊字符串傳遞作為參數(shù),最后返回其結(jié)果。然后在主入口中我們分別調(diào)用了各自的main方法,將打印出各自的name. $ python3 importer.py
foo
bar
也許你很少會代碼這么做,不過在你需要試用字符串作為導(dǎo)入路徑的話,那么importlib就有用途了。 模塊導(dǎo)入檢查Python有個眾所周知的代碼風(fēng)格EAFP: Easier to ask forgiveness than permission.它所代表的意思就是總是先確保事物存在(例如字典中的鍵)以及在犯錯時捕獲。如果我們在導(dǎo)入前想檢查是否這個模塊存在而不是靠猜。 使用mportlib就能實現(xiàn)。 import importlib.util
def check_module(module_name):
"""
Checks if module can be imported without actually
importing it
"""
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):
"""
Import the module via the passed in module specification
Returns the newly imported module
"""
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))
這里我導(dǎo)入了importlib的子模塊util。check_module里面調(diào)用find_spec方法, 傳遞該模塊字符串作為參數(shù)。當(dāng)我們分別傳入了一個不存在和存在的Python模塊。你可以看到當(dāng)你傳入不存在的模塊時,find_spec函數(shù)將返回 None,在我們代碼里就會打印提示。如果存在我們將返回模塊的specification。 我們可以通過該模塊的specification來實際導(dǎo)入該模塊?;蛘吣阒苯訉⒆址鳛閰?shù)調(diào)用import_module函數(shù)。不過我這里也學(xué)習(xí)如何試用模塊specification方式導(dǎo)入。看看import_module_from_spec函數(shù)。它接受check_module提供的模塊specification作為參數(shù)。然后我們將它傳遞給了module_from_spec函數(shù),它將返回導(dǎo)入模塊。Python文檔推薦導(dǎo)入后然后執(zhí)行模塊,所以接下來我們試用exec_module函數(shù)執(zhí)行。最后我們使用dir來確保得到預(yù)期模塊。 從源代碼導(dǎo)入importlib的子模塊有個很好用的技巧我想提提。你可以使用util通過模塊的名字和路徑來導(dǎo)入模塊。 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)
在上面的代碼中,我們實際導(dǎo)入logging模塊,并將模塊傳遞給了import_source函數(shù)。這樣我們就可以通過導(dǎo)入的模塊獲取到實際的路 徑和名字。然后我們將信息傳遞給sec_from_file_location函數(shù),它將返回模塊的specification。也了這個我們就可以在前 面那樣直接通過importlib導(dǎo)入了。 總結(jié)目前,你知道如何在代碼中使用importlib和import鉤子。這個模塊內(nèi)容非常多,如果你想自定義importer或者loader,那么你可以通過官方文檔或者源代碼了解更多。 |
|