如何理解python中的if name == “main”:

前言

使用別人的工具的時候,不知道哪裡出了錯,於是仔細看程式碼,在可能出現的模組之前加上了print(“test”),但是就是不能顯示輸出資訊。於是溯源,最後追溯到最前面的

if __name__ == "__main__":
	main()

然後發現自己不懂,由於對python的模組(module)不是很清楚,決定好好把這個知識點理清。

問題

  • __name__是什麼
  • __main__又是什麼,為什麼要加雙引號

__name__和__main__都是python的內建函式模組(模組是指以.py結尾寫好的函式的彙總)。

  • 這段程式碼放在程式最後作用又是什麼

兩個作用:一是入口點作用;二是防止在import的時候執行可執行的程式。

知識點

  • 模組(module)

一個模組被另一個程式第一次引入時,這個模組下可以被直譯器直接執行的函式將執行。

# const.py
PI = 3.14

def test():
    print("PI:", PI)

test()
print("haha")
# 執行結果:PI: 3.14
# 執行結果:haha

如果在命令列執行

py -c "import const"

其輸出將和執行const.py的結果是相同的。

類似地,當在const.py這個模組被另一個程式(如area[.]py)第一次引入時,test()和print(“haha”)將會執行。

from const import PI

def calc_round_area(radius):
    return PI * (radius ** 2)

def main():
    print("round area: ", calc_round_area(2))

main()

#輸出結果
#PI: 3.14
#haha
#round area:  12.56

理清思路

現在我們在執行程式area.py,呼叫了const.py裡的PI常量。
但是現在我們不想讓const.py中的函式test()和print()執行。

誰來拯救你?

這個時候我們的標題中的主角要登場了,他/她就是

if __name__ == "__main__":

通過在const.py中加入這句話,我們可以防止const.py裡的test()在被匯入的時候執行。
完整的程式碼如下

# const.py
PI = 3.14

def test():
    print("PI:", PI)

if __name__ == "__main__":
	test()
	print("haha")

# 執行結果:
# PI: 3.14
# haha
# area.py
from const import PI

def calc_round_area(radius):
    return PI * (radius ** 2)

def main1():
    print("round area: ", calc_round_area(2))

main1()

結語

看到網上很多都是在後面加一個main()函式,這裡的名稱只是約定俗成,我在程式碼中特意改成test, main1,都可以執行。
至於為什麼是main,這是因為從其他程式語言沿襲過來的程式入口點概念。C,C++, Java都以main函式為主函式入口點,而python沒有硬性規定這個概念,所以在用這樣的方式來實現入口點的作用。
也就是說,寫的函式可以全部是用def定義,然後再定義一個main,指向其中一個def定義的函式。
總的來說,關鍵點是import的時候會執行模組中的函式,掌握了這個知識點對模組也就理解更深了。

參考

菜鳥教程——Python3模組
Python 中的 if name == ‘main’ 該如何理解
W3CSchool_Python Modules

補充

最後憑藉這些知識點,終於找到為什麼print無輸出,因為加了

sys.stdout = sys.stdout.reconfigure(encoding='utf-8')

似乎終端不相容格式,所以不輸出顯示。