1. 寫 Python 腳本,一定要加上這個!

        共 3434字,需瀏覽 7分鐘

         ·

        2022-06-06 16:49


        大家好,我是菜鳥哥。

        使用 Python 的人,平時經(jīng)常會寫一些腳本,不管是為了提升工作效率,還是為了滿足一些特定的需求,Python 腳本都是一個常見又有用的東西。

        但是,我最近發(fā)現(xiàn)了一個以前不曾察覺的問題,就是腳本里面是否添加 if __name__ == "__main__": 這個語句,對腳本的使用其實(shí)是有很大影響的,并且這里面還有很大的學(xué)問。

        常見誤區(qū)

        很多朋友在寫腳本時比較隨意,簡單的腳本直接一溜寫下來,沒有函數(shù),順序執(zhí)行。復(fù)雜點(diǎn)的腳本,可能會加函數(shù)。這種寫法可讀性比較差,經(jīng)常讓人一眼找不到程序運(yùn)行的入口和順序。

        而 Python 社區(qū)比較推薦的寫法是在寫腳本時,加上下面這個語句:

        def?main():
        ????#?do?something
        ????print("do?something.")

        if?__name__?==?"__main__":
        ????main()

        大多數(shù)人看到這里,會不會說,這有什么,加不加這個沒那么重要吧!

        先不要忙著不屑,讓我們一起來仔細(xì)掰扯掰扯!

        有什么用

        在具體說明 if __name__ == '__main__' 的作用前,先從一個簡單的實(shí)例直觀上感受一下。

        #?const.py
        ?
        PI?=?3.14
        ?
        def?train():
        ????print("PI:",?PI)
        ?
        train()
        #?area.py
        ?
        from?const?import?PI
        ?
        def?calc_round_area(radius):
        ????return?PI?*?(radius?**?2)
        ?
        def?calculate():
        ????print("round?area:?",?calc_round_area(2))
        ?
        calculate()

        我們看下 area.py 的運(yùn)行結(jié)果:

        PI:?3.14
        round?area:??12.56

        的 PI 變量,在運(yùn)行的時候,const.py 中函數(shù) train() 中的打印也帶過來了,而我們只是引用變量,并沒有引用函數(shù),所以這是我們不愿意看到的。

        解決這個問題的方法也很簡單,我們只需在 const.py 中加上一句:

        PI?=?3.14

        def?train():
        ???print("PI:",?PI)

        if?__name__?==?"__main__":
        ???train()

        再次運(yùn)行 area.py ,輸出結(jié)果如下:

        round?area:??12.56

        這是我們預(yù)期的結(jié)果。

        程序運(yùn)行入口

        叢上述實(shí)例可以發(fā)現(xiàn),如果沒有 if __name__=="__main__": ,作為 area.py 導(dǎo)入文件時 const.py 中的所有代碼都被執(zhí)行了,而加上之后就只運(yùn)行導(dǎo)入的部分代碼。

        這就是 if __name__=="__main__": 顯而易見的作用,實(shí)際上 if __name__=="__main__": 就相當(dāng)于是 Python 模擬的程序入口。由于模塊之間相互引用,不同模塊可能都有這樣的定義,而入口程序只能有一個,選中哪個入口程序取決于 __name__ 的值。

        我們再來看一個小程序:

        #?test.py

        print("look?here")
        print(__name__)
        ?
        if?__name__?==?'__main__':
        ????print("I'm?test.py")

        程序的運(yùn)行結(jié)果如下:

        look?here
        __main__
        I'm?test.py

        可以發(fā)現(xiàn),此時變量 __name__ 的值為 __main__,所以打印 “I'm test.py”。如果運(yùn)行其他文件,通過運(yùn)行的文件調(diào)用本文件,則不會打印該語句,因?yàn)槌绦蛉肟诓粚?,該語句不執(zhí)行。

        代碼規(guī)范

        有了 if __name__=="__main__": 相當(dāng)于 Python 程序也有了一個入口函數(shù),我們可以清晰的知道程序的邏輯開始于何處,當(dāng)然還需要我們自覺的把程序的開始邏輯都放在這里。其實(shí),這也是 PyCharm 推薦的作法。

        為什么很多優(yōu)秀的編程語言,比如 C、Java、Golang、C++ 都有一個 main 入口函數(shù)呢?我想很重要的一個原因就是就是程序入口統(tǒng)一,容易閱讀。

        多進(jìn)程場景大作用

        如果你用多進(jìn)程來做并行計(jì)算,類似這樣的代碼:

        import?multiprocessing?as?mp

        def?useful_function(x):
        ????return?x?*?x

        print("processing?in?parallel")
        with?mp.Pool()?as?p:
        ????results?=?p.map(useful_function,?[1,?2,?3,?4])
        ????print(results)

        運(yùn)行這段代碼,控制臺會一直打印:

        processing?in?parallel
        processing?in?parallel
        processing?in?parallel
        processing?in?parallel
        processing?in?parallel
        processing?in?parallel
        processing?in?parallel
        processing?in?parallel
        processing?in?parallel

        并且程序會不停的報錯 RuntimeError。

        如果你加上了 if __name__=="__main__": ,程序就會按照預(yù)期的進(jìn)行:

        import?multiprocessing?as?mp

        def?useful_function(x):
        ????return?x?*?x

        if?__name__?==?'__main__':
        ????print("processing?in?parallel")
        ????with?mp.Pool()?as?p:
        ????????results?=?p.map(useful_function,?[1,?2,?3,?4])
        ????????print(results)

        Python 的多程序就是啟動了多個 Python 解器器,每個 Python 解釋器都會導(dǎo)入你這個腳本,復(fù)制一份全局變量和函數(shù)給子進(jìn)程用,如果有了 if __name__=="__main__":,那它后面的代碼就不會被 import,也就不會被重復(fù)執(zhí)行。否則,這個創(chuàng)建多進(jìn)程的代碼就會被 import,就會被執(zhí)行,從而無限遞歸的去創(chuàng)建子進(jìn)程

        總結(jié)

        if __name__=="__main__": 雖然不是強(qiáng)制的,但是我強(qiáng)列推薦你寫腳本時按照這個規(guī)范來做,它是 Python 社區(qū)的約定,對應(yīng)Python 之禪:明確優(yōu)于隱晦。




        推薦閱讀:

        入門:?最全的零基礎(chǔ)學(xué)Python的問題? |?零基礎(chǔ)學(xué)了8個月的Python??|?實(shí)戰(zhàn)項(xiàng)目?|學(xué)Python就是這條捷徑


        干貨:爬取豆瓣短評,電影《后來的我們》?|?38年NBA最佳球員分析?|? ?從萬眾期待到口碑撲街!唐探3令人失望? |?笑看新倚天屠龍記?|?燈謎答題王?|用Python做個海量小姐姐素描圖?|碟中諜這么火,我用機(jī)器學(xué)習(xí)做個迷你推薦系統(tǒng)電影


        趣味:彈球游戲? |?九宮格? |?漂亮的花?|?兩百行Python《天天酷跑》游戲!


        AI:?會做詩的機(jī)器人?|?給圖片上色?|?預(yù)測收入?|?碟中諜這么火,我用機(jī)器學(xué)習(xí)做個迷你推薦系統(tǒng)電影


        小工具:?Pdf轉(zhuǎn)Word,輕松搞定表格和水??!?|?一鍵把html網(wǎng)頁保存為pdf!|??再見PDF提取收費(fèi)!?|?用90行代碼打造最強(qiáng)PDF轉(zhuǎn)換器,word、PPT、excel、markdown、html一鍵轉(zhuǎn)換?|?制作一款釘釘?shù)蛢r機(jī)票提示器!?|60行代碼做了一個語音壁紙切換器天天看小姐姐!




        年度爆款文案

        點(diǎn)閱讀原文,看B站我的20個視頻!

        瀏覽 58
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
          
          

            1. 女人扒下男生裤子摸j | 黄色三级片免费观看 | 先锋无码 | 国二区在线播放视频 | 毛片基地视频 |