python中的封裝層級(jí)可以簡(jiǎn)單的看成:函數(shù)->類->模塊->包恩溅,其中模塊相當(dāng)于一個(gè)文件瘤礁,包是模塊的集合批狱,相當(dāng)于一個(gè)文件夾裸准。文件夾下需要__init__.py作為目錄,__init__.py也可以為空但必須存在赔硫。
一炒俱、模塊調(diào)用和靜態(tài)導(dǎo)入
在調(diào)用上,模塊和包應(yīng)該是同等級(jí)別的爪膊,即包可以看成是模塊权悟,以下以模塊代稱:
在模塊A中定義了一個(gè)函數(shù) def a(),如要在其他模塊中使用推盛,有兩種方式:
# 方式一
improt A
A.a()
# 方式二
from A improt *
a()
# 方式三
from A import a
a()
方式一和方式二三調(diào)用函數(shù)形式不同峦阁,據(jù)說方式二三是直接引用了絕對(duì)路徑所以不需要加模塊名。但這樣可能會(huì)導(dǎo)致不同模塊中的相同函數(shù)名被覆蓋(相同時(shí)以導(dǎo)入最后一個(gè)模塊為準(zhǔn))耘成。
方式二會(huì)導(dǎo)入整個(gè)A榔昔,方式三僅導(dǎo)入a部分代碼驹闰。如果頻繁使用a,建議使用方式三撒会,提高效率嘹朗。
如果想要控制方式二導(dǎo)入的模塊,即不需要全部導(dǎo)入诵肛,可以在__init__.py包含import xxx屹培,__all__=[xxx]。想要導(dǎo)入哪些模塊怔檩,加入到代碼中即可褪秀。
方式二會(huì)保護(hù)模塊A中的保護(hù)變量(以_開頭)和私有變量(以__開頭),不會(huì)對(duì)這些變量進(jìn)行導(dǎo)入薛训。方式三會(huì)導(dǎo)入這些變量媒吗,其中保護(hù)變量名稱不變,但私有變量會(huì)變成_類名__私有變量名许蓖,總之是不建議對(duì)私有變量進(jìn)行強(qiáng)行訪問蝴猪。
import就相當(dāng)于把代碼運(yùn)行了一遍调衰。
二膊爪、模塊重命名
使用from xxx import A as B,可使導(dǎo)入的部分重新命名嚎莉,適合于存在多個(gè)相同名字米酬。調(diào)用時(shí)使用B.xxx即可。
三趋箩、路徑和動(dòng)態(tài)導(dǎo)入
在模塊引用中赃额,無論是import的是相對(duì)路徑還是絕對(duì)路徑都涉及路徑的問題。
當(dāng)導(dǎo)入一個(gè)模塊時(shí)叫确,python查找順序:
- 當(dāng)前目錄
- PYTHONPATH 下的每個(gè)目錄
- 默認(rèn)路徑(安裝過程中選擇的)
以上搜索的路徑都存儲(chǔ)在sys.path中跳芳。
一些關(guān)于路徑的常用函數(shù):
os.path.abspath(__file__)可以獲得當(dāng)前模塊的絕對(duì)路徑。
os.path.dirname可以獲取當(dāng)前模塊所在文件夾路徑竹勉。
sys.path.insert(0,x)可將x插入到sys.path飞盆,import會(huì)查找sys,path,進(jìn)而找到x的路徑次乓。
改變PYTHONPATH可以使用類似set PYTHONPATH=c:\python27\lib;命令吓歇。
os.path.join(DIR,'B.py')可做拼接,最終路徑為DIR/B.py
前面所提到的三種導(dǎo)入方式都是靜態(tài)導(dǎo)入票腰,如果利用獲取路徑的函數(shù)取到了類似Dir = “E:\xxxx\xx\xxxxxx”城看,想要導(dǎo)入這個(gè)絕對(duì)地址,是無法使用靜態(tài)導(dǎo)入的杏慰,這時(shí)可以使用動(dòng)態(tài)導(dǎo)入测柠。
# 方式一
A = __import__("A")
# 方式二
A = importlib.import_module("A")
- 方式一在導(dǎo)入子模塊時(shí)會(huì)出現(xiàn)問題炼鞠,例如
__import__("ywzd.Tasks")
<module 'ywzd' from 'E:\\web_agent\\webagent3\\ywzd\\ywzd\\__init__.py'>
導(dǎo)入的依然是整個(gè)模塊,舍棄了點(diǎn)右側(cè)子模塊鹃愤。
- 方式一就算使用了fromlist簇搅,無論怎么設(shè)置依然導(dǎo)入的是整個(gè)路徑,包含點(diǎn)的子模塊软吐。
YWZD = __import__("ywzd.Tasks", fromlist=['Actions'])
<module 'ywzd.Tasks' from 'E:\\web_agent\\webagent3\\ywzd\\ywzd\\Tasks\\__init__.py'>
- 使用方式二可以導(dǎo)入想要的子模塊
import importlib
YWZD = importlib.import_module('ywzd.Tasks')
<module 'ywzd.Tasks' from 'E:\\web_agent\\webagent3\\ywzd\\ywzd\\Tasks\\__init__.py'>
四瘩将、dir()、globals()凹耙、locals()和reload()
- dir返回的是list姿现,當(dāng)前模塊的所有模塊、函數(shù)肖抱、變量备典,就是所有對(duì)象。
- globals()和locals()返回dict意述,是當(dāng)前能訪問到的所有全局變量和局部變量提佣。
- reload()則用于重新加載模塊,即重新執(zhí)行一下import荤崇。
五拌屏、特別注意
- 協(xié)程之間可以共享變量,用galobal即可术荤,將變量放在一個(gè)公共模塊中即都可以倚喂。
- 進(jìn)程之間不可共享變量,所以在初始化程序時(shí)會(huì)各自加載一次公用模塊瓣戚,可將子進(jìn)程需要區(qū)分的東西放入公用模塊中端圈,由公用模塊去讀取文件,可實(shí)現(xiàn)共享內(nèi)容子库。這種方式由于系統(tǒng)自帶對(duì)文件的讀寫鎖舱权,可以說是很安全,但是不可大量使用仑嗅,影響性能宴倍。