ทำความเข้าใจว่า __name__=='__main__' ใน Python
เผยแพร่แล้ว: 2022-08-12ในคู่มือนี้ คุณจะเข้าใจการทำงานและความสำคัญของ if __name__ == '__main__' ใน Python
คุณเคยอ่านผ่าน Python codebase ด้วยโมดูลต่างๆ หรือไม่?
ถ้าใช่ คุณอาจเคยเจอกรณี __name__ == '__main__' แบบมีเงื่อนไขในโมดูลอย่างน้อยหนึ่งโมดูล ในอีกไม่กี่นาทีข้างหน้า เราจะอธิบายให้ชัดเจนว่าเงื่อนไขข้างต้นหมายถึงอะไร และดูตัวอย่างที่เป็นประโยชน์
เอาล่ะ!
ความสำคัญของ __name__ ใน Python คืออะไร?

ใน Python โมดูลคือไฟล์ . py ที่มีคำจำกัดความของฟังก์ชัน ชุดของนิพจน์ที่จะประเมิน และอื่นๆ ตัวอย่างเช่น หากเรามีไฟล์ชื่อ hello_world.py เราจะเรียกไฟล์นี้ว่าไฟล์ hello_world.py หรือโมดูล hello_world
เมื่อคุณเรียกใช้โมดูล Python ล่าม Python จะตั้งค่าสำหรับตัวแปรพิเศษสองสามตัวก่อนดำเนินการ: __name__ เป็นหนึ่งในนั้น กุญแจสำคัญในการทำความเข้าใจความสำคัญ __name__ คือการทำความเข้าใจว่าการนำเข้าทำงานอย่างไรใน Python
ดาวน์โหลดรหัสสำหรับส่วนนี้ที่นี่
ตรงไปที่โฟลเดอร์ example-1 เรามีไฟล์ module1.py ตัวแปร __name__ อยู่ในเนมสเปซของโมดูลปัจจุบัน
โมดูลนี้พิมพ์บรรทัดตามด้วยค่าของตัวแปร __name__
# example-1/module1.py print("This is module1.") print(f"The __name__ variable of module 1 is: {__name__}.") ตอนนี้ ให้เรียกใช้ module1 จากบรรทัดคำสั่ง
$ python module1.py ในผลลัพธ์ เราจะเห็นว่าตัวแปร __name__ ถูกตั้งค่าเป็น __main__
This is module1. The __name__ variable of module 1 is: __main__.การนำเข้าโมดูลใน Python
นอกเหนือจากการเรียกใช้โมดูล Python ในบางครั้ง คุณอาจต้องการใช้ฟังก์ชันจากโมดูล Python อื่นภายในโมดูลปัจจุบัน Python อำนวยความสะดวกนี้ผ่าน การนำเข้า .
การนำเข้าทำให้คุณสามารถใช้ฟังก์ชันของโมดูลอื่นซ้ำได้ โดยการนำเข้าไปยังขอบเขตของโมดูลปัจจุบัน โดยไม่ต้องเขียนโค้ดใหม่

ไฟล์ module2.py มีดังต่อไปนี้ เราได้นำเข้า module1 ภายใน module2 2 .
# example-1/module2.py import module1 # module1 is imported print(f"This is module2") print(f"The __name__ variable of module2 is: {__name__}.") เราเรียกใช้ module2.py และสังเกตผลลัพธ์
$ python module2.pyในผลลัพธ์ด้านล่าง:
- เราเห็นว่า
module1ทำงานภายใต้ประทุนเมื่อเรานำเข้าภายในmodule2และเอาต์พุตที่เกี่ยวข้องจะถูกพิมพ์ออกมา - แต่คราวนี้ ตัวแปร __name__ ไม่ใช่ __main__ แต่เป็น
module1 - เนื่องจากเรารัน
module2โดยตรง ตัวแปร __name__ ที่สอดคล้องกับโมดูลจึงเป็น __main__
Output This is module1. The __name__ variable of module 1 is: module1. This is module2 The __name__ variable of module2 is: __main__.แนวคิดหลัก :
– หากเรียกใช้โมดูลโดยตรง ตัวแปร __name__ จะถูกตั้งค่าให้เท่ากับ __main__
– หากนำเข้าโมดูลภายในโมดูลอื่น __name__ จะถูกตั้งค่าเป็น ชื่อของโมดูล
ตัวอย่าง if __name__=='__main__' ใน Python

ในส่วนนี้ เราจะเห็นกรณีการใช้งานจริงของ if __name__ == '__main__' conditional เราจะกำหนดฟังก์ชันอย่างง่าย จากนั้นจึงเขียนการทดสอบหน่วยเพื่อตรวจสอบว่าฟังก์ชันทำงานตามที่คาดไว้หรือไม่
ดาวน์โหลดรหัสและปฏิบัติตาม
รหัสสำหรับส่วนนี้สามารถพบได้ในโฟลเดอร์ example-2
ที่นี่ add.py เป็นไฟล์ Python ที่มีคำจำกัดความของฟังก์ชัน add_ab() ฟังก์ชัน add_ab() ใช้ตัวเลขสองตัวใดก็ได้และส่งกลับผลรวม
# example-2/add.py def add_ab(a,b): return a + b 
เราจะใช้โมดูล unittest ของ Python เพื่อทดสอบฟังก์ชัน add_ab()
การเขียนกรณีทดสอบสำหรับฟังก์ชัน Python
ดูข้อมูลโค้ดด้านล่างซึ่งมีเนื้อหาของโมดูล test_add
# example-2/test_add.py import unittest from add import add_ab class TestAdd(unittest.TestCase): def test_add_23(self): self.assertEqual(add_ab(2,3), 5) def test_add_19(self): self.assertEqual(add_ab(1,9), 10) def test_add_1_minus7(self): self.assertEqual(add_ab(1,-7), -6)รหัสด้านบนทำสิ่งต่อไปนี้:

- นำเข้าโมดูล unittest ในตัวของ Python
- นำเข้าฟังก์ชัน
add_ab()จากโมดูลadd - กำหนดคลาสการทดสอบ
TestAddและชุดของกรณีทดสอบเป็นเมธอดภายในคลาสการทดสอบ
ในการตั้งค่าการทดสอบหน่วยสำหรับโค้ดของคุณ ก่อนอื่นคุณควรกำหนดคลาสการทดสอบที่สืบทอดจาก unittest.TestCase กรณีทดสอบทั้งหมดควรระบุเป็นวิธีภายในคลาสและควรเริ่มต้นด้วย test_
หมายเหตุ : หากคุณไม่ตั้งชื่อเมธอดเป็น
test_<some-descriptive-name>คุณจะเห็นว่าการทดสอบที่เกี่ยวข้องจะไม่ถูกตรวจพบ ดังนั้น จะไม่ทำงาน
ตอนนี้ ให้ลองเรียกใช้โมดูล test_add จากเทอร์มินัล
$ python test_add.pyคุณจะเห็นว่าไม่มีเอาต์พุต และไม่มีการทดสอบใดทำงาน
ทำไมถึงเป็นเช่นนี้?
เนื่องจากในการรัน unittest คุณควรรัน unittest เป็นโมดูลหลักขณะรัน test_add.py โดยใช้คำสั่งด้านล่าง
$ python -m unittest test_add.pyเมื่อรันคำสั่ง verbose ด้านบน เราจะเห็นว่าการทดสอบทั้งสามทำงานสำเร็จ
Output ... ---------------------------------------------------------------------- Ran 3 tests in 0.000s OK อย่างไรก็ตาม จะสะดวกที่จะทำการทดสอบเมื่อเรียกใช้โมดูลนี้ test_add ใช่ไหม มาเรียนรู้วิธีการทำในหัวข้อถัดไป
ใช้ if __name__ == '__main__' เพื่อเรียกใช้ unittest เป็นโมดูลหลัก

หากคุณต้องการเรียกใช้การทดสอบหน่วยทั้งหมดเมื่อโมดูลทำงานโดยตรง คุณสามารถเพิ่มเงื่อนไขได้
# example-2/test_add.py import unittest from add import add_ab class TestAdd(unittest.TestCase): def test_add_23(self): self.assertEqual(add_ab(2,3), 5) def test_add_19(self): self.assertEqual(add_ab(1,9), 10) def test_add_1_minus7(self): self.assertEqual(add_ab(1,-7), -6) # Run unittest as the main module if __name__ == '__main__': unittest.main() เงื่อนไขในข้อมูลโค้ดด้านบนจะบอกล่าม Python: หากโมดูลนี้ทำงานโดยตรง ให้รันโค้ดภายใน unittest.main() .
คุณสามารถเรียกใช้โมดูล test_add หลังจากเพิ่มโค้ดสองบรรทัดข้างต้น
$ python test_add.py️ การรันโมดูลเพิ่มการทดสอบโดยตรง จะทำการทดสอบทั้งสามแบบที่เรากำหนดไว้
Output ... ---------------------------------------------------------------------- Ran 3 tests in 0.000s OKผลลัพธ์ด้านบน OK ระบุว่าการทดสอบทั้งหมดดำเนินการสำเร็จแล้ว จุดสามจุด … ระบุว่ามีการทดสอบสามครั้งและผ่านทั้งหมด
ตอนนี้ ให้เราเปลี่ยนค่าส่งคืนที่คาดไว้ test_add_1_minus7 เป็น 8 เนื่องจากฟังก์ชันส่งคืน – 6 ในกรณีนี้ ควรมีการทดสอบที่ล้มเหลวหนึ่งครั้ง
def test_add_1_minus7(self): self.assertEqual(add_ab(1,-7), 8) ดังที่เห็นในผลลัพธ์ด้านล่าง เราได้รับ .F. จากสามการทดสอบ รูปแบบที่หนึ่งล้มเหลว (การทดสอบครั้งที่สอง) และในการติดตามกลับ เราได้รับ AssertionError ที่ระบุ – 6 != 8
Output .F. ====================================================================== FAIL: test_add_1_minus7 (__main__.TestAdd) ---------------------------------------------------------------------- Traceback (most recent call last): File "test_add.py", line 12, in test_add_1_minus7 self.assertEqual(add_ab(1,-7), 8) AssertionError: -6 != 8 ---------------------------------------------------------------------- Ran 3 tests in 0.021s FAILED (failures=1) สิ่งสำคัญประการหนึ่งที่ควรทราบคือ การทดสอบ ไม่จำเป็นต้อง รันในลำดับเดียวกับที่ระบุไว้ในคลาสการทดสอบ ในตัวอย่างข้างต้น test_add_1_minus7 ถูกกำหนดเป็นเมธอดที่สามในคลาสการทดสอบ แต่รันการทดสอบที่สอดคล้องกันเป็นครั้งที่สอง
สรุป
ฉันหวังว่าบทช่วยสอนนี้จะช่วยให้คุณเข้าใจว่าเงื่อนไข if __name__ == '__main__' ทำงานอย่างไรใน Python
ต่อไปนี้คือสรุปประเด็นสำคัญโดยย่อ:
- ล่าม Python ตั้งค่าตัวแปร __name__ ก่อนดำเนินการสคริปต์ Python
- เมื่อคุณเรียกใช้โมดูลโดยตรง ค่าของ __name__ คือ __main__
- เมื่อคุณนำเข้าโมดูลภายในสคริปต์ Python อื่น ค่าของ __name__ จะเป็นชื่อโมดูล
- คุณสามารถใช้ if __name__ == '__main__' เพื่อควบคุมการดำเนินการและส่วนใดของโมดูลที่ทำงานระหว่างการวิ่งโดยตรงและการนำเข้าตามลำดับ
ถัดไป ดูคำแนะนำเชิงลึกเกี่ยวกับชุด Python มีความสุขในการเรียนรู้!
