關於Python中的if __name__ == __main__詳情

關於在學習Python的過程中,遇到的這類似的代碼:

if __name__ == "__main__":
    print("Hello World!")

1.程序入口

對於很多編程語言來說,程序都必須要有一個入口,比如 C,C++,以及完全面向對象的編程語言 Java,C# 等。如果你接觸過這些語言,對於程序入口這個概念應該很好理解,C 和 C++ 都需要有一個 main 函數來作為程序的入口,也就是程序的運行會從 main 函數開始。同樣,Java C# 必須要有一個包含 Main 方法的主類來作為程序入口。

Python 則有不同,它屬於腳本語言,不像編譯型語言那樣先將程序編譯成二進制再運行,而是動態的逐行解釋運行。也就是從腳本第一行開始運行,沒有統一的入口。

if __name__ == “__main__”: 本質就是一個if判斷,但它又不是一個簡單的if判斷。即當.py文件運行時,__name__ 是’__main__‘ 時運行下面if下的代碼,則否不運行。當然你也可以把代碼寫成這樣:

if __name__ == "__main__":
    print("Hello World!")
else:
    print("Hello Mars!")


2.__name__是什麼?

__name__Python內置的變量,它是每個 Python 模塊必備的屬性,但它的值取決於你是如何執行這段代碼的。

當你直接執行一段腳本的時候,這段腳本的 __name__變量等於 ‘__main__
當這段腳本被導入其他程序的時候,__name__ 變量等於腳本本身的名字

場景1:直接運行腳本

假設我們有一個nameScript.py,代碼如下:

def myFunction():
    print('The value of __name__ is ' + __name__)


def main():
    myFunction()


if __name__ == '__main__':
    main()

直接執行這個文件後流程為:

在所有其他代碼執行之前,__name__變量就被設置為 ‘__main__‘ 瞭。在此之後,通過執行 def 語句,函數 main() 和 myFunction() 的本體被載入。接著,因為這個 if 語句後面的表達式為真 true,函數 main() 就被調用瞭。而 main() 函數又調用瞭myFunction(),打印出變量的值’__main__‘。

場景2:從其他腳本導入

如果你需要在其他腳本裡重用這個 myFunction() 函數,比如在 importingScript.py 裡,我們可以將 nameScript.py 作為一個模組導入。

importingScript.py 的內容如下:

import nameScript as ns

ns.myFunction()

這時,我們就有瞭兩個不同的作用域:一個是 importingScript 的,一個是 nameScript 的:

importingScript.py ,__name__ 變量就被設置為 ‘__main__‘。當導入 nameScript 的時候,Python 就在本地和環境變量 PATH 指向的路徑中尋找對應名稱的 .py 文件,找到之後,將會運行導入的文件中的代碼。

但這一次,在導入的時候,它自身的 __name__ 變量就被設置為瞭 ‘nameScript',接下來還是一樣,函數 main() myFunction() 的本體被載入。然而,這一次 if 語句後面的表達式結果為假 false,所以 main() 函數沒有被調用。

導入完畢之後,回到 importingScript.py 中。現在 nameScript 模塊中的函數定義已經被導入到當前的作用域中,於是我們通過 ns.myFunction() 的方式調用模塊中的函數,這個函數返回的是模塊內的變量的值 ‘nameScript‘。

如果你試著在 importingScript 中打印 __name__ 變量的值,那當你直接執行 importingScript 的時候,它也會輸出 ‘__main__'。原因在於,這個變量是在 importingScript 的作用域中的。

3.__name__可以顯示包路徑

我們建立這樣一個目錄結構:

a
├── b
│   ├── c.py
│   └── __init__.py
└── __init__.py
d.py


c.py文件中的代碼:

print(__name__)


d.py文件中的代碼:

from a.b import c


運行d.py文件,結果為:

a.b.c

此時a.py文件的__name__屬性變成瞭a.b.c,完完全全反映瞭它所在的包路徑。

5.測試模塊裡函數

由於一個腳本被引入時,自身的代碼會被執行,因此我們在每個腳本裡都寫上一段if __name__ == ‘__main__’: 如果你希望一些代碼隻有在腳本被直接執行時才執行,那麼就把這些代碼放入到if 語句塊中,最常見的情形就是測試代碼:

def safe_division(a, b):
    if b == 0:
        return None

    return a/b

if __name__ == '__main__':
    print(safe_division(10, 5) == 2)
    print(safe_division(10, 0) == None)

我們寫完一個函數後,不免要寫一些測試的代碼,而這些測試的代碼我們不希望他們在引入時執行,隻有當我們主動執行進行測試才執行這些測試代碼。

到此這篇關於關於Python中的if __name__ == ‘__main__‘詳情的文章就介紹到這瞭,更多相關Python中的if __name__ == ‘__main__'內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: