Python

[Python] if __name__ == “__main__” 是什麼意思?

(本文同步發表於計算思維學院

許多 Python 初學者可能常在範例程式內看到這樣的判斷式:

if __name__ == "__main__":
    function_foo()  # 或是任何你想執行的函式

如果你上網搜尋之後還是似懂非懂,這篇文章會嘗試用初學者的角度再說明一次。

首先,如果你永遠都只執行一個 Python 檔,而不引用別的檔案,那你完全不需要了解這是什麼。例如你寫了一個很棒的函式 cool.py

# cool.py
def my_cool_function():
    print("這超酷!")
print("呼叫 my_cool_function")
my_cool_function()

然後你永遠都是直接執行它,像這樣:

>> python cool.py
呼叫 my_cool_function
這超酷!

這完全沒有問題。問題出在當你想要在別的檔案中使用你在 cool.py 中定義的函式時,例如你在相同目錄下有一個 main.py

# main.py
from cool import my_cool_function
print('呼叫 cool.py 中的 my_cool_function')
my_cool_function()

當你執行 main.py 時,你預期只會看到 呼叫 cool.py 中的 my_cool_function 與 這超酷! 兩段輸出,但實際上你看到的是:

>> python main.py
呼叫 my_cool_function
這超酷!
呼叫 cool.py 中的 my_cool_function
這超酷!

看到問題了嗎?cool.py 中的主程式在被引用的時候也被執行了,原因在於:

  1. 當 Python 檔案(模組、module)被引用的時候,檔案內的每一行都會被 Python 直譯器讀取並執行(所以 cool.py 內的程式碼會被執行)
  2. Python 直譯器執行程式碼時,有一些內建、隱含的變數,__name__就是其中之一,其意義是「模組名稱」。如果該檔案是被引用,其值會是模組名稱;但若該檔案是(透過命令列)直接執行,其值會是 __main__;。

所以如果我們在 cool.py 內加入一行顯示以上訊息:

# cool.py
def my_cool_function():
    print("這超酷!")
print("__name__:", __name__) # 顯示內建的 __name__ 值
print("呼叫 my_cool_function")
my_cool_function()

再分別執行 cool.py 與 main.py,結果會是:

>> python cool.py
__name__: __main__
呼叫 my_cool_function
這超酷!
>> python main.py
__name__: cool
呼叫 my_cool_function
這超酷!
呼叫 cool.py 中的 my_cool_function
這超酷!

你可以看到 __name__ 的值在檔案被直接執行時與被引用時是不同的。所以回到上面的問題:要怎麼讓檔案在被引用時,不該執行的程式碼不被執行?當然就是靠 __name__ == "__main__"做判斷!

# cool.py
def my_cool_function():
    print("這超酷!")
if __name__: == "__main__"
	  print("呼叫 my_cool_function")
	  my_cool_function()

執行結果是:

>> python cool.py
呼叫 my_cool_function
這超酷!
>> python main.py
呼叫 cool.py 中的 my_cool_function
這超酷!

問題就完美解決了!之所以常看見這樣的寫法,是因為該程式可能有「單獨執行」(例如執行一些本身的單元測試)與「被引用」兩種情況,因此用上述判斷就可以將這兩種情況區分出來。

最後,如果你需要更簡短的說明,就直接問 ChatGPT 吧!

參考資料