新聞中心
imp —— 由代碼內(nèi)部訪問(wèn) import 。
源代碼: Lib/imp.py

目前創(chuàng)新互聯(lián)建站已為成百上千家的企業(yè)提供了網(wǎng)站建設(shè)、域名、網(wǎng)頁(yè)空間、網(wǎng)站運(yùn)營(yíng)、企業(yè)網(wǎng)站設(shè)計(jì)、魯山網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長(zhǎng),共同發(fā)展。
從版本 3.4 開(kāi)始標(biāo)記為過(guò)時(shí),將在版本 3.12 中移除。: imp 模塊已被廢棄,請(qǐng)改用 importlib。
本模塊提供了一個(gè)接口,用于實(shí)現(xiàn) import 語(yǔ)句的機(jī)制。這里定義了以下常量和函數(shù):
imp.get_magic()
返回用于識(shí)別字節(jié)編譯代碼文件 (.pyc files) 的魔術(shù)字符串值。 (該值對(duì)于各個(gè) python 版本可能不同。)
3.4 版后已移除: 改用 importlib.util.MAGIC_NUMBER。
imp.get_suffixes()
返回一個(gè) 3 元素元組的列表,每個(gè)元組描述了一個(gè)特定的模塊類(lèi)型。 每個(gè)三元組的形式為 (suffix, mode, type),其中 suffix 是要附加到模塊名稱上以組成要搜索的文件名的字符串,mode 是要傳給內(nèi)置 open() 函數(shù)以打開(kāi)該文件的模式字符串 (可以為針對(duì)文本文件的 'r' 或針對(duì)二進(jìn)制文件的 'rb'),而 type 是文件類(lèi)型,它的值為 PY_SOURCE, PY_COMPILED 之一 C_EXTENSION,具體說(shuō)明如下。
3.3 版后已移除: 改用在 importlib.machinery 上定義的常量。
imp.find_module(name[, path])
嘗試找到模塊 name。 如果 path 被省略或?yàn)?None,則會(huì)搜索 sys.path 給出的目錄名列表,但在此前會(huì)先搜索幾個(gè)特殊位置:該函數(shù)將嘗試找到具有給定名稱的內(nèi)置模塊 (C_BUILTIN),然后是凍結(jié)模塊 (PY_FROZEN),并且在某些系統(tǒng)上還會(huì)查找其他幾個(gè)位置(在 Windows 上,它將查看注冊(cè)表,其中可能指向某一特定文件)。
在其他情況下,path 必須是一個(gè)目錄名列表;將在每個(gè)目錄中搜索具有上述 get_suffixes() 所返回的任何后綴的文件。 列表中的無(wú)效名稱將被靜默地忽略(但是所有列表?xiàng)l目都必須為字符串)。
如果搜索成功,返回值將是一個(gè) 3 元素元組 (file, pathname, description):
file 是一個(gè)放在最前面的已打開(kāi)的 file object,pathname 是打到的文件的路徑名,而 description 是一個(gè)描述所找到的模塊種類(lèi)的 3 元素元組,如 get_suffixes() 所返回的列表中包含的內(nèi)容。
如果模塊為內(nèi)置或凍結(jié)模塊則 file 和 pathname 都將為 None 并且 description 元組將包含空字符串來(lái)表示其后綴和模式;模塊類(lèi)型按上述圓括號(hào)中所給出的內(nèi)容來(lái)指明。 如果搜索未成功,則會(huì)引發(fā) ImportError。 其他異常被用于指示參數(shù)或環(huán)境問(wèn)題。
如果模塊是一個(gè)包,則 file 將為 None,pathname 將為包路徑而 description 元組的最后一項(xiàng)將為 PKG_DIRECTORY。
此函數(shù)不會(huì)處理多層級(jí)的模塊名稱(包含點(diǎn)號(hào)的名稱)。 為了找到 P.M,也就是 P 包的的子模塊 M,請(qǐng)使用 find_module() 和 load_module() 來(lái)找到并載入 P 包,然后使用 find_module() 并將 path 參數(shù)設(shè)為 P.__path__。 當(dāng) P 本身也具有帶點(diǎn)號(hào)的名稱時(shí),請(qǐng)遞歸地應(yīng)用此步驟。
3.3 版后已移除: 請(qǐng)改用 importlib.util.find_spec() 除非需要兼容 Python 3.3,對(duì)于后一種情況請(qǐng)使用 importlib.find_loader()。 要查看對(duì)于前一種情況的示例用法,請(qǐng)參閱 importlib 文檔的 例子 小節(jié)。
imp.load_module(name, file, pathname, description)
加載之前由 find_module() 所找到的模塊(或由其他方式執(zhí)行搜索所產(chǎn)生的兼容的結(jié)果)。 此函數(shù)所做的不只是導(dǎo)入模塊:如果模塊已經(jīng)被導(dǎo)入,它將重新加載此模塊! name 參數(shù)指明完整的模塊名稱(包括包名,如果它是一個(gè)包的子模塊的話)。 file 參數(shù)是一個(gè)打開(kāi)的文件,而 pathname 是相應(yīng)的文件名;當(dāng)模塊是一個(gè)包或者不是從文檔加載時(shí),它們可以分別為 None 和 ''。 description 參數(shù)是一個(gè)元組,如 get_suffixes() 將返回的內(nèi)容一樣,描述了必須加載什么樣的模塊。
如果加載成功,則返回值為相應(yīng)的模塊對(duì)象;否則,將引發(fā)一個(gè)異常 (通常為 ImportError)。
重要: 調(diào)用方需負(fù)責(zé)關(guān)閉 file 參數(shù),如果它不為 None 的話,即使是在有異常被引發(fā)時(shí)。 這最好是使用 try … finally 語(yǔ)句來(lái)實(shí)現(xiàn)。
3.3 版后已移除: 如果之前是與 imp.find_module() 一起使用則可考慮使用 importlib.import_module(),在其他情況下請(qǐng)使用你選擇的 imp.find_module() 替代品所返回的加載器。 如果你直接附帶文件路徑參數(shù)調(diào)用 imp.load_module() 和相關(guān)函數(shù)則請(qǐng)使用 importlib.util.spec_from_file_location() 和 importlib.util.module_from_spec() 的組合。 參見(jiàn) importlib 文檔的 例子 小節(jié)來(lái)了解各種方式的細(xì)節(jié)。
imp.new_module(name)
返回一個(gè)新的名為 name 的空模塊對(duì)象。 此對(duì)象 不會(huì) 被插入到 sys.modules 中。
3.4 版后已移除: 請(qǐng)改用 importlib.util.module_from_spec()。
imp.reload(module)
重新加載之前導(dǎo)入的 module。 該參數(shù)必須是一個(gè)模塊對(duì)象,因此它之前必須已經(jīng)被成功導(dǎo)入了。 這在當(dāng)你已使用外部編輯器編輯過(guò)模塊源代碼文件并想在不退出 Python 解釋器的情況下嘗試新版本時(shí)會(huì)很有用處。 返回值為模塊對(duì)象(與 module 參數(shù)所指向的相同)。
當(dāng) reload(module) 被執(zhí)行時(shí):
-
Python 模塊的代碼會(huì)被重新編譯并且模塊層級(jí)的代碼將重新執(zhí)行,定義一個(gè)新的綁定到模塊字典中的名稱的對(duì)象集合。 擴(kuò)展模塊的
init函數(shù)不會(huì)被重復(fù)調(diào)用。 -
與Python中的所有的其它對(duì)象一樣,舊的對(duì)象只有在它們的引用計(jì)數(shù)為0之后才會(huì)被回收。
-
模塊命名空間中的名稱重新指向任何新的或更改后的對(duì)象。
-
其他舊對(duì)象的引用(例如那個(gè)模塊的外部名稱)不會(huì)被重新綁定到引用的新對(duì)象的,并且如果有需要,必須在出現(xiàn)的每個(gè)命名空間中進(jìn)行更新。
有一些其他注意事項(xiàng):
當(dāng)一個(gè)模塊被重新加載的時(shí)候,它的字典(包含了那個(gè)模塊的全區(qū)變量)會(huì)被保留。名稱的重新定義會(huì)覆蓋舊的定義,所以通常來(lái)說(shuō)這不是問(wèn)題。如果一個(gè)新模塊沒(méi)有定義在舊版本模塊中定義的名稱,則將保留舊版本中的定義。這一特性可用于作為那個(gè)模塊的優(yōu)點(diǎn),如果它維護(hù)一個(gè)全局表或者對(duì)象的緩存 —— 使用 try 語(yǔ)句,就可以測(cè)試表的存在并且跳過(guò)它的初始化,如果有需要的話:
try:cacheexcept NameError:cache = {}
重新加載內(nèi)置或動(dòng)態(tài)加載的模塊是合法操作但通常不是很有用處,除非是 sys, __main__ 和 builtins。 但是在許多情況下,擴(kuò)展模塊并不是被設(shè)計(jì)為可被多次初始化的,并可能在重新加載時(shí)以任意方式失敗。
如果一個(gè)模塊使用 from … import … 導(dǎo)入來(lái)自另一個(gè)模塊的對(duì)象,則為另一個(gè)模塊調(diào)用 reload() 并不會(huì)重新定義從其中導(dǎo)入的對(duì)象 —- 繞過(guò)此問(wèn)題的一種方式是重新執(zhí)行 from 語(yǔ)句,另一種方式是使用 import 和限定名稱 (module.*name*) 來(lái)代替。
如果一個(gè)模塊創(chuàng)建一個(gè)類(lèi)的實(shí)例,重新加載定義那個(gè)類(lèi)的模塊不影響那些實(shí)例的方法定義———它們繼續(xù)使用舊類(lèi)中的定義。對(duì)于子類(lèi)來(lái)說(shuō)同樣是正確的。
在 3.3 版更改: 依賴于 __name__ 和 __loader__ 而不僅是 __name__ 同時(shí)定義在被重新加載的模塊上。
3.4 版后已移除: 使用 importlib.reload() 來(lái)代替。
下列函數(shù)可以方便地處理 PEP 3147 字節(jié)編譯的文件路徑。
3.2 新版功能.
imp.cache_from_source(path, debug_override=None)
返回與源 PEP 3147 定義的 path 相關(guān)聯(lián)的已編譯字節(jié)碼文件的路徑。 舉例來(lái)說(shuō),如果 path 為 /foo/bar/baz.py 則 Python 3.2 中的返回值將是 /foo/bar/__pycache__/baz.cpython-32.pyc。 字符串 cpython-32 來(lái)自于當(dāng)前的魔術(shù)標(biāo)簽 (參見(jiàn) get_tag(); 如果 sys.implementation.cache_tag 未定義則將引發(fā) NotImplementedError)。 通過(guò)為 debug_override 傳入 True 或 False 你可以覆蓋系統(tǒng)設(shè)置的 __debug__ 值,以生成優(yōu)化的字節(jié)碼。
path 不必存在。
在 3.3 版更改: 如果 sys.implementation.cache_tag 為 None,則會(huì)引發(fā) NotImplementedError。
3.4 版后已移除: 使用 importlib.util.cache_from_source() 來(lái)代替。
在 3.5 版更改: debug_override 形參不會(huì)再創(chuàng)建 .pyo 文件。
imp.source_from_cache(path)
根據(jù)給定的 PEP 3147 文件名的 path,返回相關(guān)聯(lián)的源代碼文件路徑。 舉例來(lái)說(shuō),如果 path 為 /foo/bar/__pycache__/baz.cpython-32.pyc 則返回的路徑將是 /foo/bar/baz.py。 path 不必已存在,但是如果它未遵循 PEP 3147 格式,則會(huì)引發(fā) ValueError。 如果未定義 sys.implementation.cache_tag,則會(huì)引發(fā) NotImplementedError。
在 3.3 版更改: 當(dāng)未定義 sys.implementation.cache_tag 時(shí)將引發(fā) NotImplementedError。
3.4 版后已移除: 使用 importlib.util.source_from_cache() 來(lái)代替。
imp.get_tag()
返回與此 Python 版本魔數(shù)相匹配的 PEP 3147 魔術(shù)標(biāo)簽字符串,如 get_magic() 所返回的。
3.4 版后已移除: 從 Python 3.3 開(kāi)始直接使用 sys.implementation.cache_tag。
以下函數(shù)可以幫助與導(dǎo)入系統(tǒng)的內(nèi)部鎖定機(jī)制進(jìn)行交互。 導(dǎo)入的鎖定語(yǔ)義是一個(gè)可能在不同發(fā)布版之間發(fā)生改變的實(shí)現(xiàn)細(xì)節(jié)。 但是,Python 會(huì)確保循環(huán)導(dǎo)入操作不會(huì)出現(xiàn)任何死鎖。
imp.lock_held()
如果當(dāng)前持有全局導(dǎo)入鎖則返回 True,否則返回 False。 在沒(méi)有線程的系統(tǒng)平臺(tái)上,將總是返回 False。
在有線程的平臺(tái)上,執(zhí)行導(dǎo)入的線程首先會(huì)持有一個(gè)全局導(dǎo)入鎖,然后為導(dǎo)入其余部分設(shè)置模塊專(zhuān)屬鎖。 這將阻止其他線程導(dǎo)入相同的模塊直到原始導(dǎo)入完成,防止其他線程看到由原始線程構(gòu)建的不完整的模塊對(duì)象。 循環(huán)導(dǎo)入是個(gè)例外情況,它在構(gòu)造上就必須在某一時(shí)刻暴露不完整的模塊對(duì)象。
在 3.3 版更改: 鎖定方案在大多數(shù)情況下都已改為按模塊鎖定。 對(duì)于某些關(guān)鍵任務(wù)會(huì)保留一個(gè)全局導(dǎo)入鎖,比如初始化每個(gè)模塊的鎖。
3.4 版后已移除.
imp.acquire_lock()
為當(dāng)前線程獲取解釋器的全局導(dǎo)入鎖。 這個(gè)鎖應(yīng)當(dāng)由導(dǎo)入鉤子來(lái)使用以確保導(dǎo)入模塊時(shí)的線程安全。
一旦某個(gè)線程獲取了導(dǎo)入鎖,同一個(gè)線程可以再次獲取它而不會(huì)阻塞;該線程每次獲得它都必須再釋放它一次。
在沒(méi)有線程的平臺(tái)上,此函數(shù)將不做任何操作。
在 3.3 版更改: 鎖定方案在大多數(shù)情況下都已改為按模塊鎖定。 對(duì)于某些關(guān)鍵任務(wù)會(huì)保留一個(gè)全局導(dǎo)入鎖,比如初始化每個(gè)模塊的鎖。
3.4 版后已移除.
imp.release_lock()
釋放解釋器的全局導(dǎo)入鎖。 在沒(méi)有線程的平臺(tái)上,此函數(shù)將不做任何操作。
在 3.3 版更改: 鎖定方案在大多數(shù)情況下都已改為按模塊鎖定。 對(duì)于某些關(guān)鍵任務(wù)會(huì)保留一個(gè)全局導(dǎo)入鎖,比如初始化每個(gè)模塊的鎖。
3.4 版后已移除.
以下是在本模塊中定義的具有整數(shù)值的常量,用來(lái)表示 find_module() 的搜索結(jié)果。
imp.PY_SOURCE
模塊作為一個(gè)源文件被發(fā)現(xiàn)。
3.3 版后已移除.
imp.PY_COMPILED
模塊作為一個(gè)已編譯代碼對(duì)象文件被發(fā)現(xiàn)。
3.3 版后已移除.
imp.C_EXTENSION
模塊作為動(dòng)態(tài)可加載共享庫(kù)被發(fā)現(xiàn)。
3.3 版后已移除.
imp.PKG_DIRECTORY
模塊作為一個(gè)包目錄被發(fā)現(xiàn)。
3.3 版后已移除.
imp.C_BUILTIN
模塊作為一個(gè)內(nèi)置模塊被發(fā)現(xiàn)。
3.3 版后已移除.
imp.PY_FROZEN
模塊作為一個(gè)凍結(jié)模塊被發(fā)現(xiàn)。
3.3 版后已移除.
class imp.NullImporter(path_string)
NullImporter 類(lèi)型是一個(gè)在無(wú)法找到任何模塊時(shí)處理非目錄路徑字符串 PEP 302 導(dǎo)入鉤子。 調(diào)用此類(lèi)型時(shí)傳入一個(gè)現(xiàn)有目錄或空字符串將引發(fā) ImportError。 在其他情況下,將返回一個(gè) NullImporter 實(shí)例。
這些實(shí)例只有一個(gè)方法:
-
find_module(fullname[, path])
此方法總是返回
None,表示所請(qǐng)求的模塊無(wú)法找到。
在 3.3 版更改: 將把 None 插入到 sys.path_importer_cache 而不是 NullImporter 的實(shí)例。
3.4 版后已移除: 改為將 None 插入到 sys.path_importer_cache。
例子
以下函數(shù)模擬了 Python 1.4 及之前版本的標(biāo)準(zhǔn)導(dǎo)入語(yǔ)句(沒(méi)有多層級(jí)的模塊名稱)。 (這個(gè) 實(shí)現(xiàn) 不可用于那些版本,因?yàn)?find_module() 已經(jīng)被擴(kuò)展而 load_module() 在 1.4 中已被添加。)
import impimport sysdef __import__(name, globals=None, locals=None, fromlist=None):# Fast path: see if the module has already been imported.try:return sys.modules[name]except KeyError:pass# If any of the following calls raises an exception,# there's a problem we can't handle -- let the caller handle it.fp, pathname, description = imp.find_module(name)try:return imp.load_module(name, fp, pathname, description)finally:# Since we may exit via an exception, close fp explicitly.if fp:fp.close()
當(dāng)前題目:創(chuàng)新互聯(lián)Python教程:imp——由代碼內(nèi)部訪問(wèn)import。
文章網(wǎng)址:http://fisionsoft.com.cn/article/ccspshd.html


咨詢
建站咨詢
