if name == main ใน Python คืออะไร ใช้ตอนไหน?

   By: Withoutcoffee Icantbedev

   อัปเดตล่าสุด Feb. 19, 2024

if name == main ใน Python คืออะไร ใช้ตอนไหน?

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


Note: จะอ่านบทความนี้ได้อย่างเข้าใจ ต้องเข้าใจพื้นฐานของ Module & Package ในไพธอนก่อนครับ



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  และทำการอิมพอร์ตทั้ง  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 ซึ่งจะไว้ใช้รันเซิร์ฟเวอร์, ดีบั๊ก, ฯลฯ


สรุป

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

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


อ้างอิง


เปิดโลกการเขียนโปรแกรมและ Software Development ด้วย online courses ที่จะพาคุณอัพสกิลและพัฒนาสู่การเป็นมืออาชีพ เรียนออนไลน์ เรียนจากที่ไหนก็ได้ พร้อมซัพพอร์ตหลังเรียน

คอร์สเรียนเขียนโปรแกรม