文章目錄
- 一、初識 if __name__ == '__main__'
- 二、__name__ 和 __main__ 是什么?
- 三、實戰講解
- 四、實際應用場景
- 測試代碼
- 提高代碼可重用性
- 避免不必要的執行
- 五、深入理解和更多用法
- 使用 argparse 解析命令行參數
- 使用 unittest 進行單元測試
- 使用 multiprocessing 創建子進程
- 六、結語
今天,我要和大家聊聊一個在Python編程中看似不起眼,但其實非常關鍵的小技巧——if __name__ == '__main__'
。
一、初識 if name == ‘main’
讓我們先來看看這個神奇的代碼行:
if __name__ == '__main__':# 這里是程序的主入口main()
這行代碼,雖然簡單,卻蘊含著Python編程的精髓。它的作用是確保某些代碼塊只在模塊作為主程序運行時執行,而不是在被其他模塊導入時執行。
二、name 和 main 是什么?
-
__name__
變量每個Python模塊都有一個內置屬性
__name__
,它的值就是模塊的名字。如果模塊是被導入的,那么__name__
通常是模塊的文件名,不包括路徑和文件擴展名。 -
__main__
值當一個模塊被直接運行時,Python會將特殊變量
__name__
賦值為'__main__'
。這意味著,如果你運行一個腳本文件,__name__
將被設置為'__main__'
。而如果該模塊是被導入的,那么__name__
將被設置為模塊的名字。
三、實戰講解
示例 1:沒有 if __name__ == '__main__'
假設我們有以下代碼:
# example.py
print("This will always be executed")
def main():print("This will also be executed")
main()
當你運行example.py
:
$ python example.py
This will always be executed
This will also be executed
現在,如果我們創建另一個腳本來導入example.py
:
# test_import.py
import example
運行test_import.py
:
$ python test_import.py
This will always be executed
This will also be executed
可以看到,不論是直接運行example.py
,還是通過test_import.py
導入,example.py
里的所有代碼都會被執行。這顯然不是我們想要的結果。
示例 2:使用 if __name__ == '__main__'
我們來改進一下example.py
:
# example.py
print("This will always be executed")
def main():print("This will be executed only if run directly")
if __name__ == '__main__':main()
再次運行example.py
:
$ python example.py
This will always be executed
This will be executed only if run directly
然后運行test_import.py
:
$ python test_import.py
This will always be executed
我們發現,當example.py
被導入時,main()
函數不會被執行。這樣就達到了區分直接運行和導入執行的目的。
四、實際應用場景
測試代碼
在開發過程中,我們經常需要測試代碼段。通過if __name__ == '__main__'
,我們可以方便地在模塊底部添加測試代碼,而不用擔心它們在模塊被導入時執行:
# math_functions.py
def add(a, b):return a + b
def subtract(a, b):return a - b
if __name__ == '__main__':print("Testing add function:")print(add(1, 2)) # Should output 3print("Testing subtract function:")print(subtract(5, 3)) # Should output 2
提高代碼可重用性
很多時候,我們編寫的腳本不僅僅是一次性運行的工具,而是需要被其他模塊調用的函數庫。if __name__ == '__main__'
可以保證模塊在導入時不會執行測試代碼或其他非必要代碼,提高代碼的可重用性。
避免不必要的執行
當我們有一段需要耗時或影響全局狀態的代碼時,避免在導入時執行就顯得尤為重要:
# data_analysis.py
import pandas as pd
def load_data(filepath):data = pd.read_csv(filepath)return data
if __name__ == '__main__':filepath = 'data.csv'data = load_data(filepath)print(data.head())
在導入data_analysis.py
時,不會自動加載數據文件,只有調用模塊的相應方法才會加載數據,避免了不必要的資源占用。
五、深入理解和更多用法
使用 argparse 解析命令行參數
在寫腳本工具時,常常需要解析命令行參數。我們可以結合if __name__ == '__main__'
來實現這一功能:
# script.py
import argparse
def main():parser = argparse.ArgumentParser(description="A sample command-line tool")parser.add_argument('name', type=str, help='Your name')args = parser.parse_args()print(f'Hello, {args.name}!')
if __name__ == '__main__':main()
通過命令行運行腳本:
$ python script.py Alice
Hello, Alice!
使用 unittest 進行單元測試
在模塊中添加單元測試,用if __name__ == '__main__'
來運行測試:
# test_math_functions.py
import unittest
from math_functions import add, subtract
class TestMathFunctions(unittest.TestCase):def test_add(self):self.assertEqual(add(1, 2), 3)def test_subtract(self):self.assertEqual(subtract(5, 3), 2)
if __name__ == '__main__':unittest.main()
運行測試:
$ python test_math_functions.py
使用 multiprocessing 創建子進程
當我們需要并行處理時,使用 multiprocessing 模塊時也需要注意if __name__ == '__main__'
的使用:
# parallel_script.py
import multiprocessing
def worker(num):print(f'Worker: {num}')
if __name__ == '__main__':jobs = []for i in range(5):p = multiprocessing.Process(target=worker, args=(i,))jobs.append(p)p.start()
如果不加if __name__ == '__main__'
,在Windows系統上運行會導致無限遞歸創建子進程,最終導致崩潰。
六、結語
if __name__ == '__main__'
是Python中一個簡單卻非常重要的習慣用法,它不僅可以讓我們的代碼更加清晰和模塊化,還能避免許多潛在的問題和錯誤。
通過本文的多個示例,相信大家對if __name__ == '__main__'
的理解更加深入,并能在實際開發中靈活運用。
原文:https://mp.weixin.qq.com/s/-ckOrOBkY8f7V8ltkOyxLQ