I love Python คือ ข้อมูลชนิด ใด ในภาษา ไพ ทอน

หลาย ๆ คนที่ศึกษา กำลังศึกษาหรือเรียนไพธอน มักจะเจอโค้ด  if __name__ == '__main__': นี้กันอยู่เป็นประจำ ซึ่งทำให้เราปวดหัวและยังงงงวยกับเจ้าโค้ดนี้ และแน่นอนว่าหลายคนยังไม่รู้ว่า โค้ดภาษาไพธอนตรงส่วนนี้ทำหน้าที่อะไรกันแน่ และบทความสอนเกี่ยวกับเรื่องนี้ในไทยยังมีค่อนข้างน้อยไปจนถึงน้อยมาก เลยขอเขียนบทความนี้ขึ้นมา หวังว่าคงเป็นประโยชน์ไม่มากก็น้อย และในบทความนี้จะมาไขข้อข้องใจให้หายสงสัยกันครับ

จุดประสงค์

  1. เข้าใจและสามารถใช้งาน if __name__=='__main__': ได้เป็นอย่างดี
  2. เข้าใจเกี่ยวกับ Python Module พื้นฐานและการอิมพอร์ตโมดูลเข้ามาใช้งาน
  3. เข้าใจเกี่ยวกับ Python Package และ __init__.py ไฟล์

Python Module และ Package คืออะไร

ก่อนที่จะเข้าสู่ไฮไลท์ของเรื่อง จะขออธิบายเกี่ยวกับโมดูลและแพ็คเกจในภาษาไพธอนกันก่อนแบบภาพรวม จริง ๆ แล้ว Module ก็คือ Python File  ส่วน Package ก็คือ Folder ที่เก็บโมดูลนั่นเอง โดยแพ็คเกจนั้นจะมีไฟล์ __init__.py  กำหนดไว้ในโฟลเดอร์นั้น ๆ เพื่อบ่งบอกว่าโฟลเดอร์นี้คือ Package นั่นเอง โดยการเข้าถึง module และ package ก็จะขึ้นอยู่กับลำดับชั้นไฟล์และแพ็คเกจนั้น ๆ (File and Package Hierarchy) ขอยกตัวอย่างดังภาพด้านล่าง 


(Photo: Basic Python คอร์ส - STACKPYTHON)

และด้านล่างคือการจัดวางไฟล์และการอิมพอร์ตในรูปแบบต่าง ๆ ตามระดับของโมดูลและแพ็คเกจที่ถูกจัดวางไว้ในโปรเจคท์


การจัดวาง Package และ Module (Photo: Basic Python คอร์ส - STACKPYTHON)

"ในบทความนี้จะไม่ได้อธิบาย Module และ Package แบบละเอียดยิบ โดยจะแยกเป็นบทความในเรื่องนี้แบบเฉพาะและจะเขียนในบทความต่อ ๆ ไป แต่ก็เชื่อว่าในบทความนี้ หลาย ๆ คนคงจะเข้าใจเกี่ยวกับโมดูลและแพ็คเกจได้เป็นอย่างดีและมองภาพรวมกันออกในเบื้องต้นกันครับ"

Python Module Exercises

ลองมาทดสอบเขียนโค้ดอีกสักหน่อยเพื่อทำความเข้าใจเพิ่มเติม

tutorial1.py

#tutorial.py print("Hello, this is a Python tutorial from STACKPYTHON")

ซึ่งจากโค้ดด้านบนนั้นมีการตั้งชื่อไฟล์ว่า  tutorial.py  และก็ไม่ได้มีคำสั่งอะไรมากมาย แสดงผลเพียงแค่คำสั่ง   print("Hello, this is a Python tutorial from STACKPYTHON") ซึ่งเจ้าไฟล์นี้แหละก็คือโมดูลอย่างสมบูรณ์แบบด้วยตัวมันเอง ถึงตรงนี้หลายคนเริ่มพอจะมองภาพออกแล้ว ดังนั้นขอเสริมให้ชัดขึ้นไปอีก

ทำการสร้างไฟล์ขึ้นมาอีกหนึ่งไฟล์ที่มีชื่อว่า  tutorial2.py     

tutorial2.py

import tutorial1 print("Hello, This is the second Python file, tutorial2")

จากโค้ดด้านบนในไฟล์   tutorial2.py   นั้นจะสามารถเรียกได้ว่า ได้ทำการอิมพอร์ตโมดูล   tutorial1   มาใช้งาน ซึ่งการเรียกโมดูลนี้จะไม่ได้เรียก   .py    ซึ่งเป็นนามสกุลของไฟล์เข้าเกี่ยวข้องแล้ว และเมื่อรันโค้ดจะได้ผลลัพธ์ดังนี้

Output

Hello, this is a Python tutorial from STACKPYTHON Hello, This is the second Python file, tutorial2

ซึ่ง Hello ในบรรทัดแรกจะเป็นผลลัพธ์มาจากคำสั่ง   print("Hello, this is a Python tutorial from STACKPYTHON")    ในโมดูล   tutorial1   ซึ่งจะถูกรันก่อน เพราะได้ถูกอิมพอร์ตเข้ามาในส่วนบนสุดของไฟล์   tutorial2.py   ซึ่งแน่นอนว่าโดยปกติแล้วโค้ดนั้นจะทำงานตามลำดับ จากซ้ายไปขวาและบนลงมาล่างเสมอ

สรุปได้ว่า

  • Python Module คือ Python File 
  • Python Package คือ Folder ที่เก็บไพธอนโมดูลอีกที
  • __init__.py  คือไฟล์เปล่า ๆ ที่บ่งบอกว่าโฟลเดอร์นี้คือ Package
  • ถ้าจะเรียกไฟล์ให้เรียกว่า  tutorial1.py, tutorial2.py
  • ถ้าจะเรียกเป็นโมดูลให้ตัด .py ออกเหลือแค่ชื่อ ก็จะได้เป็นโมดูลชื่อว่า tutorial1 และ tutorial2
  • โค้ดทำงานตามลำดับจากซ้ายไปขวา บนลงมาล่าง

if __name__=='__main__':  คืออะไร ?

หลังจากทำความเข้าใจพื้นฐานก่อนหน้าที่ควรรู้ก็คือโมดูลมาเรียบร้อยแล้ว คราวนี้ก็ถึงไฮไลท์สำคัญของบทความนี้กันแล้ว โดยปกตินั้น   __name__  จะเปรียบเสมือนตัวแปรตัวแปรหนึ่งของไพธอน แต่เป็นตัวแปรชนิดพิเศษสังเกตได้อีกทางหนึ่งคือมี Dunder หรือ เครื่องหมาย Double Underscores (Name Mangling)  อยู่ในเมธอดหรือตัวแปรนั้น เช่น Dunder Methods เหล่านี้  __init__()   ,  __str__() etc

โดยปกติถ้าเราทำการรันไพธอนไฟล์ไหน ไฟล์นั้นก็จะหลายเป็น main ไฟล์ หรือ  '__main__'   โดยอัตโนมัติ

แต่เดี๋ยวก่อน อย่าเพิ่งเชื่อถ้ายังไม่ได้พิสูจน์ โดยอันดับแรกให้ทำการสร้างไฟล์ขึ้นมาสองไฟล์มีชื่อว่า   mod1.py  และ  mod2.py  

mod1.py

# mod1.py def func1(): print(f"This is mod1.py, and it is {__name__} module") func1()

สังเกตตรง   {__name__}    จะเห็นว่านี่ก็คือตัวแปร ๆ หนึ่งเพราะชัดเจนว่าสามารถอยู่ใน  { }    ซึ่งเป็นไวยากรณ์ของไพธอนในรูปแบบของ f-string ที่เราสามารถแสดงผลข้อความโดยใช้ฟังก์ชัน  print()   ตามปกติ เพียงแต่ว่ารูปแบบนี้จะทำให้สะดวกและอ่านง่ายกว่า (ในความคิดเห็นของผู้เขียน) จากนั้นทำการรันโค้ดตามปกติ

Output

This is mod1.py, and it is __main__ module

สังเกตผลลัพธ์หลังจากรันโค้ดเสร็จ จะพบว่าโมดูลนี้คือ main module ถูกต้องตามที่ได้อธิบายไปก่อนหน้านี้ 

จากนั้นทำการสร้างไฟล์ที่สองขึ้นมาที่มีชื่อว่า  mod2.py 

mod2.py

import mod1 def func2(): print(f"This is mod2.py, and it is {__name__} module") func2()

โดยในไฟล์   mod2.py   นี้จะมีการอิมพอร์ต    import mod1    โมดูลเข้ามาใช้งานด้วย จากนั้นให้ทำการรันโค้ด

Output

This is mod1.py, and it is mod1 module This is mod2.py, and it is __main__ module

อธิบายสั้น ๆ แบบกระชับได้ดังนี้

  • ผลลัพธ์ในบรรทัดแรก This is mod1.py, and it is mod1 module นั้นคือผลลัพธ์จากโมดูล     mod1  จากฟังก์ชัน   func1()   นั่นเองและชัดเจนว่าไม่ได้เป็น main โมดูล
  • ผลลัพธ์ในบรรทัดที่สอง  This is mod2.py, and it is __main__ module และก็ชัดเจนว่าในส่วนของโมดูล  mod2  นั้นก็คือ main module ก็เพราะว่ากำลังถูกรันอยู่นั่นเอง

ทดสอบใช้ if __name == '__main__':  

ให้ทำการแก้ไขไฟล์ทั้ง 2 ไฟล์ โดยเปลี่ยนแปลงโค้ดดังนี้

mod1.py

def func1(): print(f"This is mod1.py, and it is {__name__} module") def second_func_mod1(): print(f"This is the second function from mod1.py") func1() second_func_mod1()

ในส่วนของ   mod1.py   ไฟล์หรือสคริปต์นี้จะเป็นการรันและมีการประกาศและเรียกใช้งานฟังก์ชันทำงานตามปกติ ซึ่งก็จะได้ผลลัพธ์ตามปกติ

Output 1

This is mod1.py, and it is __main__ module This is the second function from mod1.py

mod2.py

import mod1 print("Running code on mod2 now") def func2(): print(f"This is mod2.py, and it is {__name__} module") def second_func_mod2(): print(f"This is the second function from mod2.py") if __name__ == '__main__': pass

ในส่วนของ   mod2.py   จะมีการกำหนดเงื่อนไขเพิ่มเติมคือถ้าในไฟล์นี้คือ main ไฟล์ให้ทำการรัน Statement หรือโค้ดด้านล่าง ซึ่งสามารถกำหนดว่าจะให้ทำอะไรได้ตามต้องการ โดยในโค้ดนี้จะยังไม่ทำอะไร โดยทำการใส่   pass   ซึ่งเป็น Python Keyword อีกตัวหนึ่งที่ใส่ไว้เพื่อไม่ให้โค้ดในส่วนนี้ว่าง ป้องกัน error ทำให้โปรแกรมยังทำงานต่อไปได้นั่นเอง

โดยโค้ดด้านบนจะได้ผลลัพธ์คล้ายคลึงกันกับ   mod1.py  เพียงแต่ว่า นอกจากเพิ่มเงื่อนไขให้รันถ้าไฟล์นี้เป็น main ไฟล์แล้วนั้น ก็ได้ทำการเพิ่มโค้ดเข้าอีกหนึ่งส่วนอยู่ด้านบนนั่นก็คือ   print("Running...") และเมื่อสังเกตผลลัพธ์ก็จะพบว่า ได้มี Output เพิ่มมาอีก 1 แถว นั่นก็คือ  Running code on mod2 now  ต่อท้ายจากผลลัพธ์ของโค้ดที่อิมพอร์ตเข้ามาจาก  import mod1 

Output 2

This is mod1.py, and it is mod1 module # mod1 This is the second function from mod1.py # mod1 Running code on mod2 now # mod2

if else คือ Control Statement ซึ่งเมื่ออ่านถึงตรงนี้คงเข้าใจกันดีแล้ว ดังนั้นเราสามารถที่จะควบคุม Statement หรือการกระทำต่าง ๆ ได้ตามต้องการ โดยสังเกตได้ดังโค้ดในโค้ดด้านล่างและสามารถปรับเปลี่ยนได้ตามต้องการ 

mod2.py 

import mod1 print("Running code on mod2 now") def func2(): print(f"This is mod2.py, and it is {__name__} module") def second_func_mod2(): print(f"This is the second function from mod2.py") # New if __name__ == '__main__': print('') func2() second_func_mod2() else: pass

Output 3

This is mod1.py, and it is mod1 module This is the second function from mod1.py Running code on mod2 now This is mod2.py, and it is __main__ module This is the second function from mod2.py

สร้างไฟล์ขึ้นมาใหม่ซึ่งเป็นไฟล์สุดท้ายชื่อว่า main.py   main.py  และทำการอิมพอร์ตทั้ง   mod1   และ  mod2   เข้ามาใช้งาน

main.py

import mod2 import mod1 print('') print("Hope you enjoy reading this article")

และเมื่อสังเกตที่ผลลัพธ์นั้นในส่วนของฟังก์ชัน   print('')   ,   func1()  และ

  second_func_mod2()  จะไม่ทำงานเนื่องจากว่าฟังก์ชันเหล่านี้กำหนดให้ทำงานในไฟล์   mod2.py   เท่านั้น ซึ่งจะรันก็ต่อเมื่อเป็น main ไฟล์ แต่ตอนนี้ main คือ  main.py   ซึ่งได้ถูกสร้างขึ้นมาใหม่ล่าสุด

Output 4

This is mod1.py, and it is mod1 module This is the second function from mod1.py Running code on mod2 now Hope you enjoy reading this article


Real use case from Flask framework

จะขอยกกรณีตัวอย่างที่หลายคนที่ได้ศึกษา Flask เฟรมเวิร์คมา โดยจะสังเกตเห็นได้ในโค้ดของ Flask ใน app.py จะมีโค้ดในส่วนของ if __name__ == '__main__':  ติดมาด้วย โดยอยู่ในส่วนล่างสุดของไฟล์

app.py

from flask import Flask app = Flask(__name__) @app.route('/') def home(): return "Hello My First Flask Project" if __name__ == '__main__': app.run(debug=True)

สรุปด้านบนแบบรวบรัดกระชับสุด ๆ เลยก็คือถ้าไฟล์ที่กำลังรันอยู่ตอนนี้คือ  app.py  และไฟล์นี้คือ main ไฟล์ ของเราเพราะว่าไฟล์กำลังถูกรันอยู่นั่นเอง และในฟังก์ชัน   app.run()   นี้ก็จะมีคำสั่งมากมายที่อยู่ใน Flask เมธอด run ซึ่งจะไว้ใช้รันเซิร์ฟเวอร์, ดีบั๊ก, ฯลฯ

บทความแนะนำสำหรับ Flask

  • ใช้งาน Flask ร่วมกับ SQLAlchemy เพื่อเชื่อมต่อฐานข้อมูล SQLite
  • ประยุกต์ใช้งาน Flask ร่วมกับ Chart.js  

คอร์สเรียนแนะนำสำหรับ Flask

  • Python Web Development with Flask - STACKPYTHON

สรุป

หลังจากอ่านจนจบบทความนี้แล้ว หวังเป็นอย่างยิ่งครับว่าจะทำให้หายข้องใจว่า if __name__ == '__main__' คืออะไร และยังมีเสริมเกี่ยวกับ Module และ Package เข้ามาด้วย เพราะว่าเป็นพื้นฐานก่อนหน้าที่ควรรู้ และขอสรุปไว้ดังนี้ครับ

  • if __name__ == '__main__': ช่วยให้สามารถที่จะเลือกรันหรือไม่รันสคริปต์หรือไฟล์ที่ต้องการได้ ซึ่งมีประโยชน์เป็นอย่างมากเกี่ยวกับการรันและการอิมพอร์ตโมดูลต่าง ๆ เข้ามาใช้งาน
  • โมดูล (Module) คือ Python ไฟล์ 
  • แพ็คเกจ (Package) คือ Folder หรือ Directory ที่เก็บ Python โมดูล
  • __init__.py เป็น Python ไฟล์ ที่บ่งบอกว่าโฟลเดอร์นี้คือแพ็คเกจ
  • __name__ คือตัวแปรชนิดหนึ่งของภาษาไพธอน ที่ใช้บอกชื่อโมดูล
  • __main__ คือ main ไฟล์ หรือไฟล์, สคริปต์ ที่กำลังรันโค้ดในขณะนั้น
  • โปรแกรมจะทำงานจาก Top Level คือทำงานจากบนลงล่าง เป็นลำดับขั้น

หากมีข้อสงสัยหรือเสนอแนะเพิ่มเติมก็คอมเมนต์เข้ามาที่คอมเมนต์ด้านล่างได้เลยนะครับ สามารถทำการล็อกอินผ่าน Facebook เพื่อคอมเมนต์และกด response emotions ต่าง ๆ ได้เลยครับ พบกันกับบทความถัดไปครับ See ya next article

| Like | Comment | Share | >> STACKPYTHON 

References 

The following are really useful resources for making this article happen

[python.org] - Top Level Script Environment

[FreeCodeCamp] - Python if __name__ == __main__ Explained with Code Examples

[//bic-berkeley.github.io/] - Two double underscores variables

Toplist

โพสต์ล่าสุด

แท็ก

แปลภาษาไทย ไทยแปลอังกฤษ แปลภาษาอังกฤษเป็นไทย pantip โปรแกรม-แปล-ภาษา-อังกฤษ พร้อม-คำ-อ่าน อาจารย์ ตจต ศัพท์ทหาร ภาษาอังกฤษ pdf lmyour แปลภาษา ชขภใ ห่อหมกฮวกไปฝากป้าmv กรมพัฒนาฝีมือแรงงาน อบรมฟรี 2566 ขขขขบบบยข ่ส ศัพท์ทางทหาร military words หนังสือราชการ ตัวอย่าง หยน แปลบาลีเป็นไทย ไทยแปลอังกฤษ ประโยค การไฟฟ้านครหลวง การไฟฟ้าส่วนภูมิภาค ข้อสอบโอเน็ต ม.3 ออกเรื่องอะไรบ้าง พจนานุกรมศัพท์ทหาร เมอร์ซี่ อาร์สยาม ล่าสุด แปลภาษามลายู ยาวี Bahasa Thailand กรมพัฒนาฝีมือแรงงาน อบรมออนไลน์ การ์ดจอมือสอง ข้อสอบคณิตศาสตร์ พร้อมเฉลย คะแนน o-net โรงเรียน ค้นหา ประวัติ นามสกุล บทที่ 1 ที่มาและความสําคัญของปัญหา ร. ต จ แบบฝึกหัดเคมี ม.5 พร้อมเฉลย แปลภาษาอาหรับ-ไทย ใบรับรอง กรมพัฒนาฝีมือแรงงาน PEA Life login Terjemahan บบบย มือปราบผีพันธุ์ซาตาน ภาค2 สรุปการบริหารทรัพยากรมนุษย์ pdf สอบโอเน็ต ม.3 จําเป็นไหม เช็คยอดค่าไฟฟ้า แจ้งไฟฟ้าดับ แปลภาษา มาเลเซีย ไทย แผนที่ทวีปอเมริกาเหนือ ่้แปลภาษา Google Translate กระบวนการบริหารทรัพยากรมนุษย์ 8 ขั้นตอน ก่อนจะนิ่งก็ต้องกลิ้งมาก่อน เนื้อเพลง ข้อสอบโอเน็ตม.3 มีกี่ข้อ คะแนนโอเน็ต 65 ตม กรุงเทพ มีที่ไหนบ้าง