1. 程式人生 > 其它 >if __name__ == __main___if __name__ == '__main__': 究竟起什麼作用,閱讀本文後,其他文章不必再看...

if __name__ == __main___if __name__ == '__main__': 究竟起什麼作用,閱讀本文後,其他文章不必再看...

技術標籤:if __name__ == __main__

def func():
    print('ok')


if __name__ == '__main__':
    func()

這種形式的程式碼,相信你已經見過很多,在指令碼的末尾,出現一個if條件判斷,這個if條件判斷的作用是什麼呢, __name__ 事先並沒有定義,為什麼可以直接使用呢,它從哪裡來? 回答這些問題,必須先了解模組屬性

1、模組屬性

一個python指令碼(以.py 結尾的檔案)就是一個模組,模組自身有若干屬性,其中比較常用的是如下兩個
1. __name__ 模組的名稱
2. __file__ 指令碼的完整檔案路徑

在任意一個python腳本里,你都可以輸出這兩個屬性

print(__name__)
print(__file__)

得到結果

__main__
/Users/zhangdongsheng/experiment/test/test.py

__name__ 的值是 __main__ ,這表示模組的名稱是__main__
__file__ 是檔案的完整路徑

雖然弄清楚了__name__ 是怎麼一回事,但也帶來了新的疑問,明明__name__ 就等於 __main__ ,為何還要做if條件判斷呢?顯然是存在 __name__ 不等於__main__ 的情況。

2、直接執行與其他模組引入

簡單的功能,我們可以在一個python腳本里完成,但複雜的功能,我們會寫多個python 指令碼,比如下面的例子裡,有兩個指令碼,一個是main.py ,做為整個程式的啟動指令碼,utils.py 提供一些輔助函式,供main.py使用

(1)utils.py

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

    return a/b

print("utils 模組裡的__name__ 值為:", __name__)

(2)main.py

from utils import safe_division

def func():
    value = input("輸入兩個整數,中間用空格分開:")
    arrs = value.split()
    a = int(arrs[0])
    b = int(arrs[1])

    result = safe_division(a, b)
    print(result)


if __name__ == '__main__':
    func()

接下來,通過兩步實驗,來理解 __name__ 在不同場景下的取值情況。

第一步,先來執行utils.py檔案

python utils.py

執行結果為

utils 模組裡的__name__ 值為: __main__

第二步,執行main.py

python main.py

執行結果為

utils 模組裡的__name__ 值為: utils
輸入兩個整數,中間用空格分開:5 2
2.5

這裡有一個現象,你必須理解其背後的原因,我們明明執行的main.py指令碼,但是utils.py腳本里的程式碼也被執行了,這是因為在main.py腳本里引入了utils.py 這個模組,被引入的腳本里的程式碼會在引入時執行。

當utils.py 被其他指令碼引入時,它的__name__ 就不等於__main__, 而是等於utils,恰好是檔名稱去掉.py 剩餘的部分。

經過上面的實驗,我們可以得出兩個結論
1. 當指令碼被直接執行時,模組屬性__name__ 等於__main__
2. 當指令碼被其他模組引入時,模組屬性__name__ 等於指令碼名稱去掉.py 後剩餘的部分

3、終極目的---測試模組裡函式

由於一個指令碼被引入時,自身的程式碼會被執行,因此我們在每個腳本里都寫上一段if __name__ == '__main__': 如果你希望一些程式碼只有在指令碼被直接執行時才執行,那麼就把這些程式碼放入到if 語句塊中,最常見的情形就是測試程式碼,下面我對utils.py 進行修改

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)

我們寫完一個函式後,不免要寫一些測試的程式碼,而這些測試的程式碼我們不希望他們在utils.py被引入時執行,只有當我們主動執行utils.py 進行測試才執行這些測試程式碼

掃一掃,更多專業python技術分享

f91ff0d750105bf4259ab5204a4b5a07.png