🇯🇵 日本語 | 🇺🇸 English | 🇪🇸 Español | 🇵🇹 Português | 🇹🇭 ไทย | 🇨🇳 中文

[สำหรับมือใหม่ Python] ไม่ต้องกลัว IndentationError! อดีตมือใหม่สอนสาเหตุและวิธีแก้ปัญหาสุดเร็ว

สวัสดีครับทุกคน! ผมที่เคยไม่มีความรู้ด้านโปรแกรมมิ่งเลยเมื่อไม่กี่เดือนก่อน ได้ใช้ประสบการณ์จากการสร้างเว็บไซต์ 2 แห่งในเดือนครึ่งด้วยความช่วยเหลือของ AI มาอธิบายจุดที่มือใหม่มักจะติดขัดกันครับ

เมื่อเริ่มเรียน Python ข้อความแสดงข้อผิดพลาดสีแดงที่หลายคนน่าจะเจอเป็นอันดับแรก... และในบรรดาข้อผิดพลาดเหล่านั้น ข้อผิดพลาดที่ทำให้ปวดหัวและสงสัยว่า "เอ๊ะ ทำไม? ผิดตรงไหน?" ก็น่าจะเป็น IndentationError ที่เราจะมาอธิบายกันในครั้งนี้

ตอนแรกผมก็เป็นเหมือนกันครับ เคยเสียเวลาไปหลายชั่วโมงเพียงเพราะการเว้นวรรคผิดไปแค่ช่องเดียว จนเคยคิดว่า "สงสัยเราจะไม่เหมาะกับการเขียนโปรแกรมซะแล้ว..." แต่ไม่ต้องกังวลครับ! ถ้าได้อ่านบทความนี้ IndentationError จะไม่น่ากลัวอีกต่อไป สาเหตุนั้นง่ายอย่างไม่น่าเชื่อ และเมื่อเข้าใจแล้ว คุณจะไม่สับสนอีกเลย

ในบทความนี้ ผมจะอธิบายถึงสาเหตุและวิธีแก้ไขข้อผิดพลาดจาก "มุมมองของคนที่เป็นมือใหม่เหมือนกัน" โดยอ้างอิงจากประสบการณ์ที่ผมเคยเจอมาจริงๆ รวมถึงมาตรการป้องกันเพื่อไม่ให้คุณต้องเจอกับปัญหานี้อีก ผมได้เตรียมโค้ดที่สามารถคัดลอกและนำไปใช้ได้ทันทีไว้มากมาย มาลองสัมผัสประสบการณ์ "โค้ดทำงานได้!" ไปด้วยกันเถอะครับ!


ทำไม Python ถึงเข้มงวดเรื่องการย่อหน้า (Indentation) ขนาดนี้?

สำหรับผู้ที่เคยเห็นภาษาโปรแกรมมิ่งอื่นๆ (เช่น JavaScript หรือ C) มาบ้าง อาจจะสงสัยว่า "ทำไมแค่ Python ถึงเกิดข้อผิดพลาดจากการย่อหน้า?"

ในหลายๆ ภาษา จะใช้เครื่องหมาย { } (วงเล็บปีกกา) ในการกำหนด "บล็อก" ของโค้ด แบบนี้ครับ

// นี่คือตัวอย่างของ JavaScript
if (x > 10) {
  console.log("x มากกว่า 10");
  console.log("บรรทัดนี้ก็อยู่ในบล็อกเดียวกัน");
}

ถ้ามี { } ก็จะเห็นได้ชัดเจนว่าส่วนไหนเป็นเนื้อหาของ if โปรแกรมจะยังคงทำงานได้แม้ว่าการย่อหน้าจะไม่เป็นระเบียบก็ตาม

ในทางกลับกัน ปรัชญาการออกแบบของ Python คือ "โค้ดที่อ่านง่ายคือโค้ดที่ดี" เพื่อให้โค้ดที่ใครเขียนก็ดูสะอาดตาและอ่านง่ายเหมือนกัน Python จึงใช้การย่อหน้าแทน { } เพื่อแสดงถึงบล็อกของโค้ด

พูดง่ายๆ ก็คือ สำหรับ Python แล้ว การย่อหน้าไม่ใช่แค่เรื่องของความสวยงาม แต่เป็นไวยากรณ์ที่กำหนดโครงสร้างของโค้ดโดยตรง

บล็อกของโค้ดที่ตามหลังเครื่องหมายโคลอน (:) และมีการย่อหน้าเข้าไปหนึ่งระดับ นี่คือสัญญาณของ "บล็อก" ใน Python

# นี่คือตัวอย่างของ Python
age = 20
if age >= 20:
    # ส่วนนี้ถูกย่อหน้า จึงเป็น "บล็อก" ของ if
    print("คุณเป็นผู้ใหญ่แล้ว")
    print("สามารถดื่มเหล้าและสูบบุหรี่ได้")
# ส่วนนี้ไม่ได้ย่อหน้า จึงอยู่นอก if
print("สิ้นสุดการทำงานของโปรแกรม")

3 สาเหตุหลักของ IndentationError และคู่มือการแก้ไขฉบับสมบูรณ์

งั้นเรามาดู 3 สาเหตุหลักที่ทำให้เกิด IndentationError และวิธีแก้ไขของแต่ละสาเหตุกันเลยครับ

สาเหตุที่ 1: การย่อหน้าไม่เพียงพอ (expected an indented block)

นี่คือข้อผิดพลาดที่ Python กำลังบอกคุณว่า "ตรงนี้ต้องมีบล็อกที่ย่อหน้านะ!" หลังจากบรรทัดที่ลงท้ายด้วยโคลอน (:), เช่น if, for, def, class จะต้องมีการย่อหน้าเสมอ

ข้อผิดพลาดที่พบบ่อย 👎

# โค้ดที่ทำให้เกิดข้อผิดพลาด
name = "Taro"
if name == "Taro":
print("สวัสดี, คุณ Taro!") # บรรทัดถัดจาก if ไม่ได้ย่อหน้า

เมื่อรันโค้ดนี้ จะเกิดข้อผิดพลาด IndentationError: expected an indented block

วิธีแก้ไข 👍
ให้ทำการย่อหน้า (Indentation) บรรทัดถัดจากโคลอน (:) ด้วยการเว้นวรรค 4 ครั้ง ใน Editor ส่วนใหญ่ การกดปุ่ม Tab หนึ่งครั้งจะเทียบเท่ากับการเว้นวรรค 4 ครั้งโดยอัตโนมัติ

ให้จำไว้เหมือนคาถาเลยว่า "หลังโคลอน ให้ย่อหน้าหนึ่งระดับ"

# โค้ดที่ทำงานได้อย่างถูกต้อง
name = "Taro"
if name == "Taro":
    # ย่อหน้าด้วยการเว้นวรรค 4 ครั้ง
    print("สวัสดี, คุณ Taro!") 

สาเหตุที่ 2: การย่อหน้ามากเกินไป (unexpected indent)

อันนี้จะตรงกันข้ามกับเมื่อสักครู่ เป็นการบ่นจาก Python ว่า "ตรงนี้ไม่ต้องการการย่อหน้านะ..." ข้อผิดพลาดนี้จะเกิดขึ้นเมื่อคุณทำการย่อหน้าโดยไม่มีเหตุผล

ข้อผิดพลาดที่พบบ่อย 👎

# โค้ดที่ทำให้เกิดข้อผิดพลาด
print("เริ่มการทำงาน")
    print("บรรทัดนี้ถูกย่อหน้าโดยไม่มีเหตุผล") # การย่อหน้าที่ไม่มีเหตุผล
print("สิ้นสุดการทำงาน")

เมื่อรันโค้ดนี้ จะเกิดข้อผิดพลาด IndentationError: unexpected indent

วิธีแก้ไข 👍
การย่อหน้าจะใช้เพื่อระบุจุดเริ่มต้นของบล็อกคำสั่ง เช่น if หรือ for เท่านั้น ในตำแหน่งอื่นๆ ให้เริ่มเขียนโค้ดจากต้นบรรทัด

ให้คิดไว้เสมอว่า "คำสั่งในระดับเดียวกัน ให้อยู่ในแนวเดียวกัน" จะทำให้เข้าใจง่ายขึ้น

# โค้ดที่ทำงานได้อย่างถูกต้อง
print("เริ่มการทำงาน")
print("บรรทัดนี้ไม่ต้องย่อหน้า") # ลบการย่อหน้าออก
print("สิ้นสุดการทำงาน")

สาเหตุที่ 3: การใช้ Space และ Tab ปนกัน (tab error)

นี่คือ "ศัตรูที่มองไม่เห็น" ที่น่ารำคาญที่สุดสำหรับมือใหม่ แม้ว่าภายนอกจะดูเหมือนย่อหน้าเหมือนกัน แต่ถ้าบางบรรทัดใช้ "การเว้นวรรค 4 ครั้ง" และอีกบรรทัดใช้ "การกด Tab หนึ่งครั้ง" Python จะสับสนและแสดงข้อผิดพลาด

ปัญหานี้มักเกิดขึ้นเมื่อคัดลอกและวางโค้ดจากเว็บไซต์ ผมเองก็เสียเวลากับเรื่องนี้ไปหลายครั้ง...

วิธีแก้ไข 👍
ในการแก้ปัญหานี้ สิ่งสำคัญคือต้องทำให้ "ศัตรู" มองเห็นได้ก่อน Code Editor ที่คุณใช้ (เช่น Visual Studio Code) จะมีฟังก์ชันในการแสดงสัญลักษณ์แทน Space และ Tab อยู่เสมอ

ตัวอย่างเช่นใน VS Code คุณสามารถเลือก "Render Whitespace" จากเมนู "View" หรือตั้งค่า "editor.renderWhitespace": "all" เพื่อให้ Space แสดงเป็นจุด (·) และ Tab แสดงเป็นลูกศร (→)

ตัวอย่างการแสดงอักขระว่างใน Visual Studio Code โดย Space จะแสดงเป็นจุด และ Tab จะแสดงเป็นลูกศร (รูปภาพนี้เป็นเพียงภาพจำลองการแสดงอักขระว่าง)

เมื่อมองเห็นแล้ว ให้มองหาจุดที่มีการย่อหน้าปนกันและเปลี่ยนทั้งหมดให้เป็น "การเว้นวรรค 4 ครั้ง" Editor หลายตัวมีฟังก์ชันในการแปลง Tab ทั้งหมดในไฟล์เป็น Space ได้ในครั้งเดียว

มาตรฐานการเขียนโค้ดอย่างเป็นทางการของ Python (PEP 8) ก็แนะนำอย่างยิ่งให้ใช้การเว้นวรรค 4 ครั้งในการย่อหน้า หากไม่มีเหตุผลพิเศษ ควรปฏิบัติตามกฎนี้

# วิธีเขียนที่แนะนำ
def my_function():
    # การย่อหน้านี้ใช้การเว้นวรรค 4 ครั้ง
    print("ย่อหน้าด้วยการเว้นวรรค 4 ครั้ง")
    if True:
        # การย่อหน้านี้ใช้การเว้นวรรค 8 ครั้ง (4 * 2)
        print("เมื่อมีการซ้อน (nest) จะเพิ่มการย่อหน้าเข้าไปอีก 4 ครั้ง")

[เทคนิคการเรียนรู้ในยุค AI] เคล็ดลับการปรึกษา AI เกี่ยวกับ IndentationError

เมื่อเกิดข้อผิดพลาด การปรึกษา AI อย่าง ChatGPT เป็นวิธีที่มีประสิทธิภาพมาก ผมเองก็ใช้เป็นประจำ แต่คุณภาพของคำตอบที่ได้จะแตกต่างกันมาก ขึ้นอยู่กับวิธีการถาม

ตัวอย่างคำถามที่ไม่ดี 👎

เกิด IndentationError ช่วยแก้ให้หน่อย

แบบนี้ AI จะมีข้อมูลไม่เพียงพอและให้ได้แค่คำตอบทั่วๆ ไป

ตัวอย่างคำถามที่ดี (Prompt) 👍

เมื่อรันโค้ด Python ต่อไปนี้แล้วเกิดข้อผิดพลาด `IndentationError: expected an indented block`

1. สาเหตุของข้อผิดพลาดคืออะไร?
2. ควรแก้ไขบรรทัดไหน อย่างไร และขอโค้ดทั้งหมดหลังการแก้ไขด้วย

▼ โค้ดที่ทำให้เกิดข้อผิดพลาด

# วางโค้ดของคุณที่นี่
name = "Taro"
if name == "Taro":
print("สวัสดี, คุณ Taro!")

การให้ข้อมูลครบชุดแบบนี้:

  1. ข้อความแสดงข้อผิดพลาดที่ชัดเจน
  2. โค้ดทั้งหมดที่ทำให้เกิดข้อผิดพลาด
  3. สิ่งที่ต้องการทราบ (สาเหตุและแนวทางแก้ไข)

จะทำให้ AI เข้าใจสถานการณ์ของคุณได้อย่างถูกต้องและให้แนวทางแก้ไขที่แม่นยำ มาใช้ AI ให้เป็นเหมือนครูสอนพิเศษส่วนตัวที่ยอดเยี่ยมกันเถอะ


ไม่พลาดอีกต่อไป! มาตรการป้องกัน IndentationError อย่างถาวร

สุดท้ายนี้ ผมจะแนะนำมาตรการป้องกันที่ทรงพลังที่สุด เพื่อไม่ให้เกิด IndentationError ตั้งแต่แรก

นั่นคือ การติดตั้งเครื่องมือจัดรูปแบบโค้ด (Code Formatter)

ใน Python มีเครื่องมืออย่าง `Black` หรือ `autopep8` ที่จะช่วยจัดรูปแบบโค้ดของคุณให้สวยงามตามมาตรฐาน PEP 8 โดยอัตโนมัติทุกครั้งที่บันทึกไฟล์

หากคุณตั้งค่าสิ่งนี้ใน Code Editor ของคุณ ปัญหาการย่อหน้าที่ไม่ตรงกัน หรือการใช้ Space และ Tab ปนกัน จะถูกแก้ไขโดยอัตโนมัติทันทีที่คุณบันทึกไฟล์ คุณจะหมดภาระในการแก้ไขการย่อหน้าด้วยตนเอง และสามารถมุ่งเน้นไปที่การคิดตรรกะของโปรแกรมได้อย่างเต็มที่

คุณสามารถหาวิธีการติดตั้งได้จากบทความมากมายโดยการค้นหาคำว่า "ตั้งค่า Black ใน VSCode" การลงทุนลงแรงเพียงเล็กน้อยในครั้งนี้ จะช่วยประหยัดเวลาในการพัฒนาของคุณไปได้หลายสิบชั่วโมงในอนาคต


สรุป: การย่อหน้าคือ "มารยาท" ของ Python

ในครั้งนี้ เราได้อธิบายถึงสาเหตุและวิธีแก้ไข IndentationError โดยอ้างอิงจากประสบการณ์ของผม

การย่อหน้าเปรียบเสมือน "มารยาท" ของภาษา Python ในตอนแรกอาจจะรู้สึกอึดอัดเล็กน้อย แต่เมื่อคุณคุ้นเคยกับมารยาทนี้แล้ว คุณจะสามารถเขียนโค้ดที่สวยงาม อ่านง่าย และบำรุงรักษาได้ง่ายสำหรับทุกคน

เมื่อคุณก้าวข้ามข้อผิดพลาดนี้ไปได้ คุณก็ได้ก้าวไปอีกขั้นบนเส้นทางสู่การเป็นผู้เชี่ยวชาญ Python แล้ว มาเรียนรู้ไปด้วยกันต่อไปนะครับ!

ขั้นตอนต่อไป

หลังจากที่คุณเชี่ยวชาญเรื่องการย่อหน้าแล้ว ข้อผิดพลาดต่อไปที่คุณมักจะเจอคือ `SyntaxError` ซึ่งเป็นข้อผิดพลาดทางไวยากรณ์โดยตรง มาเรียนรู้เกี่ยวกับรูปแบบที่พบบ่อย เช่น การลืมปิดวงเล็บ หรือการลืมใส่โคลอน และวิธีแก้ไขกันเถอะ

→ อ่านบทความถัดไป: ข้อผิดพลาดที่พบบ่อยและวิธีแก้ไขสำหรับ SyntaxError