if __name__ == "__main__" 是什麼意思?
本文解釋了 Python 程式碼表達式if __name__ == '__main__' 的含義。
Python 程式使用條件 `if __name__ == '__main__'` 僅在程式由 Python 直譯器 直接執行時才執行 if 語句內的程式碼。當檔案的程式碼作為模組匯入時,if 語句內的程式碼不會被執行。
什麼是 __main__?
"__name__" 在 Python 中表示一個特殊的變數。
Python 有許多以雙下劃線開頭和結尾的特殊變數。為了簡便起見,它們被稱為 dunder(來自 Double Underscores)。在本例中,"__name__" 讀作“dunder name”。
讓我們使用 Python shell 來確定 __main__ 的值:
>>> __name__ '__main__'
因此,__name__ 的值為 __main__。
讓我們嘗試匯入一個 Python 模組,看看分配給模組的 __name__ 變數的值:
>>> import random >>> random.__name__ 'random'
因此,匯入 random 模組 後,我們可以看到 __name__ 的值為 'random',這實際上就是它的名稱。
Python __name__ 變數的值
編寫以下程式碼並將其放在檔案 __name__main.py 中:
print(" __name__ value is {}".format(__name__))
一條使用字串格式化方法輸出 __name__ 值的 print 命令。
當我們直接引用 Python 檔案執行程式碼時,__name__ 的值為 __main__:
$ python __name__main.py The value of __name__ is __main__
相反,如果我們透過 Python shell 匯入模組,__name__ 的值為 __name__main:
>>> import _name_main __name__ value is __name__main
因此,__name__ 的值取決於我們 Python 程式碼的執行方式。
__name__ 的示例
要在 Python 中使用條件 `if __name__ == "__main__"`,我們建立一個如下所示的 Python 程式,其中呼叫三個不同的函式:
def step1(): print("Executing the first step...") def step2(): print("Executing the second step...") def step3(): print("Executing the third step...") step1() step2() step3()
輸出
以下是上述程式碼的輸出:
Executing the first step... Executing the second step... Executing the third step...
假設另一個 Python 應用程式需要使用 step1() 函式。我們需要將我們的檔案作為模組匯入來實現這一點。
當我們這樣做時會發生什麼:
>>> import _name_main Executing the first step... Executing the second step... Executing the third step... >>> _name_main.step1() Executing the first step...
匯入模組後,可以呼叫 step1() 函式。問題是,當我們匯入模組時,以下三行會自動執行:
step1() step2() step3()
現在問題是——我們如何阻止這種情況發生?
檢查模組匯入時 __name__ 是否等於 __main__
我們可以檢查 __name__ 的值是否等於 "__main__" 來阻止上一節中看到的行為。
這樣,只有在直接呼叫 Python 檔案而不是將其作為模組匯入時,if 條件內的程式碼才會執行。
示例
現在,程式是:
def step1(): print("Executing the first step...") def step2(): print("Executing the second step...") def step3(): print("Executing the third step...") if __name__ == "__main__": step1() step2() step3()
輸出
讓我們檢查一下直接呼叫 Python 程式是否仍然會呼叫這三個函式。
Executing the first step... Executing the second step... Executing the third step...
此外,當我們將其作為模組匯入時,這三個函式不會被執行;
>>> import _name_main >>> _name_main.step1() Executing the first step...
這次好多了!
假設 _name_main 模組有數百個函式,並非所有函式都需要匯入。
如何只匯入 step1() 函式?
應使用以下語法:
>>> from _name_main import step1 >>> step1() Executing step1... >>> step2() Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'step2' is not defined
如您所見,在本例中,我們只匯入了 step1 函式的成功版本。
當我們嘗試執行 step2() 時,會發生 `NameError: name 'step2' is not defined` 錯誤。
Python 中的主方法
在像 Java 或 C 這樣的語言中,main 的概念非常常見,它指定程式執行的起點。
在 Python 中經常使用的main()函式在 if 語句內執行,並檢查 __name__ 變數的值。
為了獲得特定的結果,main() 函式中呼叫了幾個函式。在本例中,main 函式將呼叫三個子函式:
示例
def step1(): print("Executing the first step...") def step2(): print("Executing the second step...") def step3(): print("Executing the third step...") def main(): step1() step2() step3() if __name__ == "__main__": main()
輸出
Executing the first step... Executing the second step... Executing the third step...
由於 main 的概念也為其他開發人員所熟知,因此將函式命名為 main() 只是一種標準的命名約定,可以提高程式的可讀性。
實際上,沒有任何東西阻止我們將 main 函式重新命名為其他名稱。
在繼續本文之前,請驗證我們修改後的程式碼在兩種情況下都能正常工作:
- 直接執行程式碼
- 匯入模組
__name__、__main__ 和 Python 中的引數
當在確定變數 __name__ 是否等於 "__main__" 的 if 條件內直接呼叫我們的 Python 程式時,我們可以處理傳遞給程式的任何引數。
我們可以使用sys 模組來處理傳遞給程式的引數。
匯入 sys 模組。
建立一個名為 main() 的函式,它只接受一個引數。這個引數將是一個包含傳遞給程式的引數的字串列表。
作為 if 語句的一部分(該語句檢查 __name__ 變數的值),將 sys.argv 傳遞給 main() 函式。
示例
import sys def main(args): print(args) if __name__ == "__main__": main(sys.argv)
輸出
以下是上述已執行程式的輸出:
['main.py']
如您所見,Python 程式的第一個引數是 .py 檔案本身的名稱。
讓我們修改 main 方法,使其列印 args 變數的型別。
def main(args): print(type(args)) print(args)
這證明了 args 是一個列表:
$ python arguments.py arg1 arg2 <class 'list'> ['arguments.py', 'arg1', 'arg2']
除了提供引數外,我們還可以解包程式需要的引數,不包括程式的名稱:
import sys def main(c, d): return int(c) * int(d) if __name__ == "__main__": arg1, arg2 = sys.argv[1:3] print(main(arg1, arg2))
以下是我們執行程式的步驟以及我們獲得的結果:
$ python product.py 4 5 20
這段程式碼使用切片運算子獲取命令列上提供的兩個數字。然後將這兩個數字以字串格式傳遞給 main() 方法。
然後,main 函式返回這兩個數字轉換為整數的結果。