ทำความเข้าใจว่า __name__=='__main__' ใน Python

เผยแพร่แล้ว: 2022-08-12

ในคู่มือนี้ คุณจะเข้าใจการทำงานและความสำคัญของ if __name__ == '__main__' ใน Python

คุณเคยอ่านผ่าน Python codebase ด้วยโมดูลต่างๆ หรือไม่?

ถ้าใช่ คุณอาจเคยเจอกรณี __name__ == '__main__' แบบมีเงื่อนไขในโมดูลอย่างน้อยหนึ่งโมดูล ในอีกไม่กี่นาทีข้างหน้า เราจะอธิบายให้ชัดเจนว่าเงื่อนไขข้างต้นหมายถึงอะไร และดูตัวอย่างที่เป็นประโยชน์

เอาล่ะ!

ความสำคัญของ __name__ ใน Python คืออะไร?

ความสำคัญของ __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 อำนวยความสะดวกนี้ผ่าน การนำเข้า .

การนำเข้าทำให้คุณสามารถใช้ฟังก์ชันของโมดูลอื่นซ้ำได้ โดยการนำเข้าไปยังขอบเขตของโมดูลปัจจุบัน โดยไม่ต้องเขียนโค้ดใหม่

การนำเข้าโมดูลใน 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__' ใน 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 เป็นโมดูลหลัก

รัน 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 มีความสุขในการเรียนรู้!