python中_init_.py的作用
最近有幾個小伙伴問了我一個經(jīng)典問題:“__init__.py 到底有啥用?”
其實這個問題挺常見的,尤其是對Python新手來說簡直就是一團(tuán)迷霧。今天就站在一位老程序員的角度來給大家嘮一嘮__init__.py的用途和奧秘,順便幫大家“踩踩坑”,看看有哪些用法需要注意。
1. __init__.py 是個啥?
__init__.py,顧名思義,這個文件名就透露出它是用來“初始化”的。在Python里,它主要用于標(biāo)識一個目錄是一個“包(Package)”。
你在項目里新建了一個文件夾,要讓它成為一個可供導(dǎo)入的模塊包,最簡單的辦法就是在里面加一個__init__.py。
比如,咱們有個項目結(jié)構(gòu)如下:
當(dāng)我們想要在外部使用my_project這個包時,就可以這樣導(dǎo)入:
有了__init__.py的存在,Python才知道m(xù)y_project是一個包,而不是一個普通的文件夾。
所以這個文件的基本作用就是:告訴Python,“這里是個包,你可以在其他地方導(dǎo)入我!”
2. __init__.py 還能做些啥?
很多初學(xué)者以為這個文件只能“聲明”包,實際上它的用法比你想象的要豐富得多。在__init__.py里你可以編寫代碼,它會在包被導(dǎo)入時自動執(zhí)行。這有什么用呢?我給大家舉幾個常見的例子:
模塊初始化操作
假如你有一個需要初始化配置的工具包,你可以在__init__.py里直接搞定這些初始化工作。
這樣,當(dāng)你一導(dǎo)入my_project時,config.yaml就被自動加載了,是不是很方便?你再也不用在每個子模塊里重復(fù)配置路徑啦!
控制子模塊導(dǎo)入
通過在__init__.py中用from .sub_module import some_function的方式,可以直接在import package_name的時候就將所有常用的子模塊或者函數(shù)導(dǎo)入,這樣你就能從包的頂級目錄直接訪問子模塊的內(nèi)容了:
你看,這種做法就好比你開了一個餐廳,顧客剛一進(jìn)門就能看到招牌菜,這樣體驗就好了,少了很多繞路時間。
包級別變量和函數(shù)的初始化
你還可以在__init__.py里設(shè)置一些全局變量,或者定義一些包級別的工具函數(shù)。
這樣在任何地方,只要你導(dǎo)入了my_project,就能直接調(diào)用show_info()了。
3. __init__.py 的一些“坑”
俗話說得好,“有光的地方就有陰影”。別看__init__.py這么實用,里面也有不少坑,尤其是**循環(huán)導(dǎo)入(Circular Import)**的問題,這個坑可是踩一次懷疑人生那種級別的。
什么是循環(huán)導(dǎo)入?
假設(shè)你有兩個模塊module1和module2,然后你在module1.py中寫了這樣一段代碼:
然后你又在module2.py里這樣寫:
這就會導(dǎo)致Python在導(dǎo)入包的時候出現(xiàn)死循環(huán),結(jié)果是兩邊互相等待對方加載,最終就會報錯或者無法正常導(dǎo)入。
如何解決?
一般來說,解決方案有兩種:
延遲導(dǎo)入:將導(dǎo)入語句放在函數(shù)內(nèi)部,而不是放在文件頭部。
重構(gòu)代碼結(jié)構(gòu):把相互依賴的部分提取出來,放到一個公共模塊里,這樣兩個模塊就不會直接互相依賴了。
4. __init__.py 和相對導(dǎo)入的關(guān)系
另外,再講一個可能讓人頭疼的點——相對導(dǎo)入和絕對導(dǎo)入。很多小伙伴可能會在__init__.py里用相對導(dǎo)入的語法,比如:
乍看上去沒啥問題,但等到你跑module1.py這個文件時,就會發(fā)現(xiàn)——Boom!報錯了!因為相對導(dǎo)入的方式要求你必須從頂層包開始導(dǎo)入。而你直接執(zhí)行module1.py,Python根本不知道它是從哪個包里來的。
解決方案呢?我建議——盡量使用絕對導(dǎo)入,比如這樣:
這樣不管你是直接運(yùn)行module1.py,還是導(dǎo)入整個my_project,都不會有問題。
5. 還有哪些小技巧?
說了這么多,最后再給大家提幾個小技巧,幫你在使用__init__.py時少走彎路:
避免復(fù)雜邏輯:不要在__init__.py中寫太復(fù)雜的業(yè)務(wù)邏輯。它的職責(zé)應(yīng)該是輕量級的初始化和導(dǎo)入,不然以后維護(hù)起來會非常麻煩。
模塊導(dǎo)出控制:你可以用__all__來控制從包中導(dǎo)出哪些模塊或變量。
這樣當(dāng)你用from my_project import *時,Python只會導(dǎo)入__all__指定的內(nèi)容。
合并子模塊:你可以在__init__.py中把子模塊的功能合并到一個命名空間中,讓用戶使用起來更方便。
記錄導(dǎo)入順序:如果你的包里有很多子模塊,建議記錄導(dǎo)入順序,避免因為導(dǎo)入順序?qū)е乱恍┰幃惖腂ug。
總體來說,__init__.py用得好,它能讓整個包管理得井井有條,用得不好,它就會變成你代碼里的“絆腳石”。
到此這篇關(guān)于python中_init_.py的作用的文章就介紹到這了,更多相關(guān)python _init_.py內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python中的異常處理try/except/finally/raise用法分析
這篇文章主要介紹了Python中的異常處理try/except/finally/raise用法,結(jié)合實例形式分析了Python異常處理try/except/finally/raise相關(guān)功能與使用操作技巧,并附帶了Python常見異常的表格說明,需要的朋友可以參考下2019-02-02使用Python爬了4400條淘寶商品數(shù)據(jù),竟發(fā)現(xiàn)了這些“潛規(guī)則”
這篇文章主要介紹了使用Python爬了4400條淘寶商品數(shù)據(jù),竟發(fā)現(xiàn)了這些“潛規(guī)則”,筆者用 Python 爬取淘寶某商品的全過程,并對商品數(shù)據(jù)進(jìn)行了挖掘與分析,最終得出結(jié)論。需要的朋友可以參考下2018-03-03python使用Tkinter顯示網(wǎng)絡(luò)圖片的方法
這篇文章主要介紹了python使用Tkinter顯示網(wǎng)絡(luò)圖片的方法,涉及Python操作圖片的相關(guān)技巧,需要的朋友可以參考下2015-04-04四種Python機(jī)器學(xué)習(xí)超參數(shù)搜索方法總結(jié)
在建模時模型的超參數(shù)對精度有一定的影響,而設(shè)置和調(diào)整超參數(shù)的取值,往往稱為調(diào)參。本文將演示在sklearn中支持的四種基礎(chǔ)超參數(shù)搜索方法,需要的可以參考一下2022-11-11