在python中一個(gè).py文件就是一個(gè)模塊俊戳,使用模塊既可以保證代碼的重用性惨奕,又能增強(qiáng)程序的結(jié)構(gòu)性和可維護(hù)性雪位。對(duì)于內(nèi)置模塊和第三方模塊提供的現(xiàn)成功能的拿來主義能極大的提高程序員的開發(fā)效率。
首次導(dǎo)入模塊做三件事:
1梨撞、執(zhí)行源文件代碼
2雹洗、產(chǎn)生一個(gè)新的命名空間用于存放源代碼執(zhí)行過程中產(chǎn)生的名字
3、在當(dāng)前執(zhí)行文件的名稱空間生成一個(gè)名字指向新創(chuàng)建的模塊命名空間卧波,引用模塊命名空間中的名字要加上模塊名前綴时肿。
第一次導(dǎo)入模塊將其加載到內(nèi)存空間,之后的重復(fù)導(dǎo)入就會(huì)直接從內(nèi)存中加載已存在的模塊港粱,不會(huì)重復(fù)執(zhí)行導(dǎo)入螃成,通過sys.modules可以查看內(nèi)存中已加載的模塊名。
模塊名應(yīng)該遵循小寫形式查坪。
模塊按分類導(dǎo)入:內(nèi)置模塊寸宏,第三方模塊,自定義模塊偿曙,雖然能通過逗號(hào)分隔不同的模塊击吱,但建議每行只導(dǎo)入一個(gè)模塊,這種行為更加規(guī)范遥昧,可讀性更強(qiáng)覆醇。
我們也可以在函數(shù)中導(dǎo)入模塊,對(duì)比在文件頭部導(dǎo)入模塊術(shù)語全局作用域炭臭,在函數(shù)內(nèi)導(dǎo)入模塊則屬于局部作用域永脓。
模塊內(nèi)變量的導(dǎo)入不加前綴的好處是能使我們的代碼更簡(jiǎn)潔,但是也會(huì)容易和當(dāng)前名稱空間內(nèi)的名字發(fā)生沖突鞋仍,如果當(dāng)前名稱空間存在相同的名字常摧,后定義的名字會(huì)覆蓋之前定義的名字。
只能在模塊最頂層使用 from module import *這種導(dǎo)入方式威创,在函數(shù)內(nèi)是非法的.這種方式很容易產(chǎn)生名稱沖突落午。模塊中可以定義__all__這個(gè)列表變量來存儲(chǔ)要導(dǎo)出的變量名(from module import * 會(huì)自動(dòng)導(dǎo)入__all__中定義的名字。不在all中的名字對(duì)外沒有導(dǎo)出看不到的肚豺。)
循環(huán)導(dǎo)入問題指的是在一個(gè)模塊加載/導(dǎo)入的過程中導(dǎo)入另外一個(gè)模塊溃斋,而在另外一個(gè)模塊中又返回來導(dǎo)入第一個(gè)模塊中的名字,由于第一個(gè)模塊尚未加載完畢吸申,所以引用失敗梗劫、拋出異常享甸,究其根源就是在python中,同一個(gè)模塊只會(huì)在第一次導(dǎo)入時(shí)執(zhí)行其內(nèi)部代碼梳侨,再次導(dǎo)入該模塊時(shí)蛉威,即便是該模塊尚未完全加載完畢也不會(huì)去重復(fù)執(zhí)行內(nèi)部代碼
模塊的四個(gè)通用級(jí)別:
1、使用純python代碼寫的.py文件
2走哺、包含一系列模塊額包
3蚯嫌、使用C編寫的鏈接到python解釋器上的內(nèi)置模塊。
4丙躏、使用C或C++編譯的擴(kuò)展模塊择示。
導(dǎo)入一個(gè)模塊時(shí),如果模塊已加載在內(nèi)存中彼哼,則直接引用对妄,否則會(huì)優(yōu)先查找內(nèi)置模塊湘今,然后按從左到右的順序依次檢索sys.path中定義的路徑敢朱,知道找到模塊對(duì)應(yīng)的文件為止,否則拋出異常摩瞎。
sys.path第一個(gè)路徑通常為空拴签,代表執(zhí)行文件所在的目錄,所以被導(dǎo)入模塊與執(zhí)行文件在同一目錄下肯定是可以正常導(dǎo)入的旗们。而針對(duì)被導(dǎo)入模塊和執(zhí)行文件不在同一目錄的情況蚓哩,為了確保模塊對(duì)應(yīng)的文件能被找到,文件所在的路徑目錄需要被添加到sys.path中上渴。
包是一個(gè)包含__init__.py文件的文件夾岸梨,文件夾內(nèi)可以組織子模塊或子包。
注意:在python3中稠氮,即使包中沒有__init__.py文件曹阔,import導(dǎo)入也不會(huì)報(bào)錯(cuò),在python2中隔披,包中必須包含該文件赃份,否則就會(huì)報(bào)錯(cuò)。包的存在是為了導(dǎo)入使用而不是直接運(yùn)行奢米,包是模塊的一種形式而已抓韩,包本質(zhì)就是一種模塊。
包屬于模塊的一種鬓长,包以及包內(nèi)的模塊均是用來被導(dǎo)入使用的谒拴,而絕非被直接執(zhí)行,首次導(dǎo)入包會(huì)做三件事:
1涉波、執(zhí)行包下的__init__.py文件
2彪薛、產(chǎn)生一個(gè)新的名稱空間用于存放_(tái)_init__.py執(zhí)行過程中產(chǎn)生的名字茂装。
3、在當(dāng)前執(zhí)行文件所在的名稱空間得到一個(gè)指向__init__.py名稱空間的名字善延。導(dǎo)入包時(shí)并不會(huì)導(dǎo)入包下所有的子模塊與子包少态。
包的導(dǎo)入語句分import和from ... import.. 在導(dǎo)入時(shí)都必須遵循一個(gè)原則:凡是在導(dǎo)入時(shí)帶點(diǎn)的,點(diǎn)的左邊都必須是一個(gè)包易遣。
import導(dǎo)入文件時(shí)彼妻,產(chǎn)生名稱空間中的名字來源于文件,import 包豆茫,產(chǎn)生的名稱空間的名字同樣來源于文件侨歉,即包下的__init__.py,導(dǎo)入包本質(zhì)就是在導(dǎo)入該文件揩魂。
針對(duì)包內(nèi)模塊間的相互導(dǎo)入推薦使用相對(duì)導(dǎo)入幽邓。相對(duì)導(dǎo)入只能在包內(nèi)使用,用相對(duì)導(dǎo)入不同目錄下的模塊是非法的火脉。無論Import還是from-import 凡是在導(dǎo)入時(shí)帶點(diǎn)的牵舵,點(diǎn)的左邊必須是包,否則會(huì)語法錯(cuò)誤倦挂。