在Python當(dāng)中,如果代碼寫得規(guī)范一些,通常會(huì)寫上一句“if __name__==’__main__:”作為程序的入口,但似乎沒(méi)有這么一句代碼,程序也能正常運(yùn)行。這句代碼多余嗎?原理又在哪里?本篇博文對(duì)此進(jìn)行總結(jié)說(shuō)明。
學(xué)過(guò)Java、C、C++的程序員應(yīng)該都知道,每次開(kāi)啟一個(gè)程序,都必須寫一個(gè)主函數(shù)作為程序的入口,也就是我們常說(shuō)的main函數(shù)。如下所示, main()就是Java中的一個(gè)main函數(shù)。
public class HelloWorld {public static void main(String[] args) { System.out.println("HelloWorld"); }}
與Java、C、C++等幾種語(yǔ)言不同的是,Python是一種解釋型腳本語(yǔ)言,在執(zhí)行之前不同要將所有代碼先編譯成中間代碼,Python程序運(yùn)行時(shí)是從模塊頂行開(kāi)始,逐行進(jìn)行翻譯執(zhí)行,所以,最頂層(沒(méi)有被縮進(jìn))的代碼都會(huì)被執(zhí)行,所以Python中并不需要一個(gè)統(tǒng)一的main()作為程序的入口。在某種意義上講,“if __name__==’__main__:”也像是一個(gè)標(biāo)志,象征著Java等語(yǔ)言中的程序主入口,告訴其他程序員,代碼入口在此——這是“if __name__==’__main__:”這條代碼的意義之一。
我們知道,當(dāng)我們把模塊A中的代碼在模塊B中進(jìn)行import A時(shí),只要B模塊代碼運(yùn)行到該import語(yǔ)句,模塊A的代碼會(huì)被執(zhí)行。
模塊A:
# 模塊Aa = 100print('你好,我是模塊A……')print(a)
模塊B:
# 模塊Bfrom package01 import Ab = 200print('你好,我是模塊B……')print(b)
運(yùn)行模塊B時(shí),輸出結(jié)果如下:
你好,我是模塊A……
100
你好,我是模塊B……
200
如果在模塊A中,我們有部分的代碼不想在被導(dǎo)入到B時(shí)直接被運(yùn)行,但在直接運(yùn)行A時(shí)可直接運(yùn)行,那該怎么做呢?那就可以用到“if __name__==’__main__:”這行代碼了,我們隊(duì)上面用到的A模塊代碼進(jìn)行修改:
A模塊代碼修改為:
# 模塊Aa = 100print('你好,我是模塊A……')if __name__=='__main__':print(a)
B模塊不做修改,直接執(zhí)行B模塊,輸出結(jié)果如下:
你好,我是模塊A……
你好,我是模塊B……
200
看到了嗎,A模塊中的a的值就沒(méi)有再被輸出了。所以,當(dāng)你要導(dǎo)入某個(gè)模塊,但又不想改模塊的部分代碼被直接執(zhí)行,那就可以這一部分代碼放在“if __name__=='__main__':”內(nèi)部。
看到現(xiàn)在也許心中還是疑惑,為什么會(huì)這樣,那么現(xiàn)在我們來(lái)說(shuō)一說(shuō)“if __name__=='__main__':”的原理。
“__name__”是Python的內(nèi)置變量,用于指代當(dāng)前模塊。我們修改上面用到的A模塊和B模塊,在模塊中分別輸出模塊的名稱:
模塊A:
# 模塊Aprint('你好,我是模塊A……')print('模塊A中__name__的值:{}'.format(__name__))print('-------------------------')
模塊B:
# 模塊Bfrom package01 import Aprint('你好,我是模塊B……')print('模塊B中__name__的值:{}'.format(__name__))
執(zhí)行A模塊時(shí),輸出結(jié)果:
你好,我是模塊A……
模塊A中__name__的值:__main__
-------------------------
執(zhí)行B模塊時(shí),輸出結(jié)果:
你好,我是模塊A……
模塊A中__name__的值:package01.A
-------------------------
你好,我是模塊B……
模塊B中__name__的值:__main__
發(fā)現(xiàn)神奇之處了嗎?當(dāng)哪個(gè)模塊被直接執(zhí)行時(shí),該模塊“__name__”的值就是“__main__”,當(dāng)被導(dǎo)入另一模塊時(shí),“__name__”的值就是模塊的真實(shí)名稱。用一個(gè)類比來(lái)解釋一下:記得小時(shí)候要輪流打算教室,輪到自己的時(shí)候(模塊被直接執(zhí)行的時(shí)候),我們會(huì)說(shuō)今天是“我”(__main__)值日,稱呼其他人時(shí),我們就會(huì)直接喊他們的名字。所以,“__main__”就相當(dāng)于當(dāng)事人,或者說(shuō)第一人稱的“我”。
所以,當(dāng)運(yùn)行“if __name__=='__main__':”語(yǔ)句時(shí),如果當(dāng)前模塊時(shí)被直接執(zhí)行,__name__的值就是__main__,條件判斷的結(jié)果為True,“if __name__=='__main__':”下面的代碼塊就會(huì)被執(zhí)行。
“if __name__=='__main__':”語(yǔ)句的用處與原理大概也講清楚了,如果沒(méi)說(shuō)明白,或者是我沒(méi)理解到位,請(qǐng)給我留言。另外多說(shuō)一句,“if __name__=='__main__':”很多時(shí)候看似無(wú)用,但是,出于代碼的規(guī)范性,還是有必要的。
聯(lián)系客服