Python - __name__ == '__main__' 到底是什麼意思
總結
之所以常看見這樣的寫法,是因為該程式可能有“單獨執行”(例如執行一些單元測試)與“被引用”兩種情況,鑑於這兩種情況中__name__的值是不同的:
- 當一個模組被直接執行時,其__name__必然等於__main__;
- 當一個模組被引用時,其__name__必然等於檔名(不含.py)
所以利用判斷__name__ == '__main__'的真假就可以將這兩種情況區分出來。
詳細說明
相信許多人初學 Python 時,常會在例子程式中看到如下語句:
if __name__ == '__main__':
foo() # 或其他語句
第 1 行的__name__ == '__main__'到底是什麼意思呢?
首先,如果你永遠都只執行一個 xxx.py,而不去 import它的話,那你完全不需要了解這是什麼。例如你寫了一個程式,檔名叫 hello.py
print("====this is hello.py====")
def foo():
print("hello")
print("call foo() which is defined here")
foo()
print("====this is hello.py END ====")
然後你總是直接執行它,就像這樣
$ python3 hello.py
====this is hello.py====
call foo() which is defined here
hello
====this is hello.py END ====
這完全沒有問題。
但是,當別人想引用你的foo()函式時,就有問題了。
例如別人寫了一個檔案,名字是 world.py
# world.py
print("====this is world.py====")
from hello import foo
print("call foo() which is defined in other file")
foo()
print("====this is world.py END ====")
執行結果如下:
$ python3 world.py
====this is world.py====
====this is hello.py====
call foo() which is defined here
hello
====this is hello.py END ====
call foo() which is defined in other file
hello
====this is world.py END ====
可以看到,直譯器是逐行解釋原始碼的,當執行到原始碼的第 3 行時,也就是 hello.py 被引用時,hello.py 的每一行都會被直譯器讀取並執行,執行效果就是結果中的3~6行,然後直譯器執行原始碼的5~7行。
如果你不想要結果中的3~6行,該怎麼做呢?
Python 直譯器執行程式碼時,有一些內建、隱含的變數,__name__就是其中之一,其意義是“模組名稱”。
如果該模組是被引用,那麼__name__的值會是此模組的名稱;如果該模組是直接被執行,那麼__name__的值是__main__。
或許你還不明白,那我們來做個實驗。
# hello.py
print("====this is hello.py====")
print(__name__)
def foo():
print("Ha")
print("call foo() which is defined here")
foo()
print("====this is hello.py END ====")
請注意上面第3行
# world.py
print("====this is world.py====")
print(__name__)
from hello import foo
print("call foo() which is defined in other file")
foo()
print("====this is world.py END ====")
同樣,請注意上面第3行
我們看一下執行結果。
對於第一個:
$ python3 hello.py
====this is hello.py====
__main__
call foo() which is defined here
Ha
====this is hello.py END ====
從結果的第3行可以看出,對於直接執行的模組,其模組名是 __main__
對於第二個:
$ python3 world.py
====this is world.py====
__main__ # 因為 world.py 被直接執行,所以這裡的值是 __main__
====this is hello.py====
hello # 因為 hello.py 被引用,所以這裡的值是 hello
call foo() which is defined here
Ha
====this is hello.py END ====
call foo() which is defined in other file
Ha
====this is world.py END ====
注意到第5行了嗎?這裡的“hello”正是 hello.py 被引用時的模組名稱。
由此可見,__name__的值在模組被直接執行時與被引用時是不同的。
回到上面的問題:當一個模組被引用時,如何不執行該模組的語句?答案就是靠判斷__name__是否等於 __main__。當一個模組被直接執行時,其__name__必然等於__main__;當一個模組被引用時,其__name__必然等於檔名(不含.py);
參考文獻
版權宣告:本文為CSDN博主「車子 chezi」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處連結及本宣告。
原文連結:https://blog.csdn.net/longintchar/article/details/87120496