ข้ามไปยังเนื้อหาหลัก
Editor

อ่าน error ใน Python ให้เป็น และแก้บั๊กที่พบบ่อย

เริ่มต้น20 นาที6 แบบฝึกหัด75 XP

บทเรียนนี้แปลจากต้นฉบับภาษาอังกฤษRead in EnglishLeer en españolЧитать на русскомLer em portuguêsแจ้งข้อผิดพลาดในการแปล

0/6 แบบฝึกหัด

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

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

ในบทเรียนนี้ คุณจะได้เรียนวิธีอ่าน traceback ของ Python ทำความเข้าใจ error หกชนิดที่พบบ่อยที่สุด และสร้างชุดวิธีคิดสำหรับแก้บั๊กได้อย่างรวดเร็ว

วิธีอ่าน traceback ของ Python

เมื่อ Python เจอข้อผิดพลาด มันจะแสดง traceback ซึ่งเป็นรายงานที่บอกว่าเกิดอะไรขึ้น คนส่วนใหญ่อ่าน traceback จากบนลงล่าง ซึ่งเป็นการอ่านกลับด้าน ให้เริ่มอ่านจาก บรรทัดสุดท้าย เสมอ

โค้ดที่ทำให้เกิด traceback
def greet(name):
message = 'Hello, ' + name
return message
result = greet(42)
ผลลัพธ์
Traceback (most recent call last):
  File "<exec>", line 5, in <module>
  File "<exec>", line 2, in greet
TypeError: can only concatenate str (not "int") to str

เมื่อรันโค้ดนี้ Python จะแสดง traceback ออกมา นี่คือวิธีอ่าน โดยเริ่มจากด้านล่าง:


SyntaxError: Python ไม่เข้าใจโค้ดของคุณ

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

สาเหตุที่พบบ่อยของ SyntaxError
# Missing colon after if
try:
exec('if True\n print("hello")')
except SyntaxError as e:
print(f'SyntaxError: {e}')
# These are the most common causes:
print('Common SyntaxError causes:')
print('1. Missing colon after if/else/for/while/def')
print('2. Mismatched parentheses or quotes')
print('3. Using = instead of == in conditions')
print('4. Incorrect indentation')
ผลลัพธ์
SyntaxError: expected ':' (<string>, line 1)
Common SyntaxError causes:
1. Missing colon after if/else/for/while/def
2. Mismatched parentheses or quotes
3. Using = instead of == in conditions
4. Incorrect indentation

ข่าวดีคือ SyntaxError มักแก้ง่ายที่สุด Python มักชี้ไปที่ปัญหาตรงๆ ด้วยลูกศรเล็กๆ (^) ที่แสดงจุดที่มันสับสน

ผิด: ไม่มีโคลอน
if temperature > 30
    print('Hot!')
แก้แล้ว: เติมโคลอน
if temperature > 30:
    print('Hot!')

NameError: Python หาชื่อนั้นไม่เจอ

NameError หมายความว่าคุณใช้ชื่อตัวแปรหรือชื่อฟังก์ชันที่ Python ไม่รู้จัก โดยปกติแปลว่าคุณพิมพ์ผิด ลืมสร้างตัวแปร หรือใช้ตัวแปรก่อนกำหนดค่าให้มัน

ตัวอย่าง NameError ที่พบบ่อย
# Typo in variable name
username = 'Alice'
try:
print(usernme) # Oops - misspelled!
except NameError as e:
print(f'NameError: {e}')
# Using a variable before defining it
try:
print(score)
score = 100
except NameError as e:
print(f'NameError: {e}')
ผลลัพธ์
NameError: name 'usernme' is not defined
NameError: name 'score' is not defined
บั๊ก: พิมพ์ชื่อตัวแปรผิด
total_price = 49.99
print(total_prce)  # typo!
แก้แล้ว: สะกดถูกต้อง
total_price = 49.99
print(total_price)

TypeError: ชนิดข้อมูลไม่เหมาะกับการดำเนินการ

TypeError หมายความว่าคุณพยายามทำบางอย่างกับข้อมูลผิดชนิด เช่น บวกสตริงกับตัวเลข หรือเรียกสิ่งที่ไม่ใช่ฟังก์ชัน Python รู้ว่าคุณต้องการอะไร แต่ชนิดข้อมูลไม่ตรงกัน

ตัวอย่าง TypeError ที่พบบ่อย
# Can't add string and integer
try:
result = 'Age: ' + 25
except TypeError as e:
print(f'TypeError: {e}')
# Can't multiply string by string
try:
result = 'hello' * 'world'
except TypeError as e:
print(f'TypeError: {e}')
# Wrong number of arguments
def add(a, b):
return a + b
try:
add(1, 2, 3)
except TypeError as e:
print(f'TypeError: {e}')
ผลลัพธ์
TypeError: can only concatenate str (not "int") to str
TypeError: can't multiply sequence by non-int of type 'str'
TypeError: add() takes 2 positional arguments but 3 were given

TypeError มักโผล่ขึ้นมาเมื่อทำงานกับข้อมูลที่ผู้ใช้ป้อน (ซึ่งเป็นสตริงเสมอ) หรือเมื่อฟังก์ชันคืนค่า None โดยไม่คาดคิด

บั๊ก: ผสมสตริงกับ int
age = 25
print('You are ' + age + ' years old')
แก้แล้ว: ใช้ f-string หรือ str()
age = 25
print(f'You are {age} years old')

IndexError และ KeyError: เข้าถึงสิ่งที่ไม่มีอยู่

IndexError เกิดเมื่อคุณพยายามเข้าถึงตำแหน่งในลิสต์ที่ไม่มีอยู่ KeyError เกิดเมื่อคุณพยายามเข้าถึงคีย์ของดิกชันนารีที่ไม่มีอยู่ ทั้งสองแบบหมายความว่าคุณกำลังหยิบสิ่งที่ไม่มีอยู่ตรงนั้น

ตัวอย่าง IndexError และ KeyError
# IndexError - list index out of range
fruits = ['apple', 'banana', 'cherry']
try:
print(fruits[5]) # Only indices 0, 1, 2 exist!
except IndexError as e:
print(f'IndexError: {e}')
print(f'List length: {len(fruits)}')
print(f'Valid indices: 0 to {len(fruits) - 1}')
# KeyError - dictionary key doesn't exist
user = {'name': 'Alice', 'age': 25}
try:
print(user['email']) # This key doesn't exist!
except KeyError as e:
print(f'KeyError: {e}')
ผลลัพธ์
IndexError: list index out of range
List length: 3
Valid indices: 0 to 2
KeyError: 'email'

สำหรับดิกชันนารี คุณเลี่ยง KeyError ได้ด้วยเมธอด .get() ซึ่งคืนค่าเริ่มต้นแทนที่จะทำให้โปรแกรมหยุดทำงาน

หยุดทำงานด้วย KeyError
user = {'name': 'Alice'}
email = user['email']  # KeyError!
ปลอดภัยด้วย .get()
user = {'name': 'Alice'}
email = user.get('email', 'Not provided')
print(email)  # Not provided

ValueError: ชนิดถูก แต่ค่าผิด

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

ตัวอย่าง ValueError ที่พบบ่อย
# Can't convert "hello" to an integer
try:
number = int('hello')
except ValueError as e:
print(f'ValueError: {e}')
# Can't convert a decimal string with int()
try:
number = int('3.14')
except ValueError as e:
print(f'ValueError: {e}')
# This works - go through float first
number = int(float('3.14'))
print(f'Converted: {number}')
ผลลัพธ์
ValueError: invalid literal for int() with base 10: 'hello'
ValueError: invalid literal for int() with base 10: '3.14'
Converted: 3

ValueError เกิดบ่อยเมื่อประมวลผลข้อมูลที่ผู้ใช้ป้อน ผู้ใช้อาจพิมพ์ "ยี่สิบ" แทน "20" หรือปล่อยช่องว่างไว้ ควรตรวจสอบข้อมูลก่อนแปลงชนิดเสมอ

จัดการ ValueError ด้วย try/except
# Safe conversion pattern
user_input = 'abc'
try:
age = int(user_input)
print(f'Your age is {age}')
except ValueError:
print(f'\"{user_input}\" is not a valid number')
ผลลัพธ์
"abc" is not a valid number

เคล็ดลับการดีบักที่ใช้บ่อย

นี่คือคู่มือสั้นๆ สำหรับดีบักโค้ด Python เทคนิคเหล่านี้ใช้ได้กับข้อผิดพลาดทุกชนิด

นี่คือตารางสรุปข้อผิดพลาดที่คุณจะเจอบ่อยที่สุด:

ข้อผิดพลาดความหมายวิธีแก้เร็วๆ
SyntaxErrorโครงสร้างโค้ดผิดตรวจโคลอน วงเล็บ เครื่องหมายคำพูด
NameErrorหาตัวแปร/ฟังก์ชันไม่เจอตรวจการสะกด สร้างก่อนใช้
TypeErrorชนิดข้อมูลผิดแปลงชนิดข้อมูล หรือตรวจอาร์กิวเมนต์ของฟังก์ชัน
IndexErrorดัชนีลิสต์เกินขอบเขตตรวจความยาวลิสต์ จำไว้ว่าดัชนีเริ่มที่ 0
KeyErrorไม่พบคีย์ในดิกชันนารีใช้ .get() หรือตรวจว่ามีคีย์นั้นอยู่
ValueErrorชนิดถูก ค่าผิดตรวจสอบข้อมูลก่อนแปลงชนิด

แบบฝึกหัด

ถึงเวลาฝึกทักษะการดีบักแล้ว แบบฝึกหัดส่วนใหญ่ให้โค้ดที่มีบั๊กมาให้คุณแก้ อ่านข้อความแจ้งข้อผิดพลาด หาบั๊ก แล้วซ่อมให้ถูก

แบบฝึกหัดที่ 1: แก้ SyntaxError
แก้บั๊ก

โค้ดนี้มี SyntaxError หาแล้วแก้ให้แสดงผล:

Python is fun!
Let's learn more.
message = 'Python is fun!'
print(message
print('Let\'s learn more.')
แบบฝึกหัดที่ 2: แก้ NameError
แก้บั๊ก

โค้ดนี้มี NameError หาจุดที่พิมพ์ผิดแล้วแก้ให้แสดงผล:

Hello, Alice! You have 3 new messages.
user_name = 'Alice'
message_count = 3
print(f'Hello, {user_name}! You have {mesage_count} new messages.')
แบบฝึกหัดที่ 3: แก้ TypeError
แก้บั๊ก

โค้ดนี้มี TypeError แก้ให้แสดงผล:

Your total is $37.5
price = 12.5
quantity = '3'
total = price * quantity
print(f'Your total is ${total}')
แบบฝึกหัดที่ 4: แก้ IndexError
แก้บั๊ก

โค้ดนี้พยายามแสดงสีสุดท้าย แต่หยุดทำงานด้วย IndexError แก้ให้แสดงผล:

Last color: green
colors = ['red', 'blue', 'green']
last_index = len(colors)
print(f'Last color: {colors[last_index]}')
แบบฝึกหัดที่ 5: แก้ ValueError
แก้บั๊ก

โค้ดนี้หยุดทำงานเมื่อพยายามแปลงสตริงราคาเป็นจำนวนเต็ม แก้ให้แสดงผล:

Price in cents: 999

ราคาคือ "9.99" ดอลลาร์ และเราต้องการแปลงเป็นเซนต์ (คูณด้วย 100 แล้วแปลงผลลัพธ์เป็นจำนวนเต็ม)

price_str = '9.99'
price_cents = int(price_str) * 100
print(f'Price in cents: {price_cents}')
แบบฝึกหัดที่ 6: แก้บั๊กทั้งหมด
แก้บั๊ก

โค้ดนี้พังในทุกส่วนทั้งสามส่วน แม้ว่าการแก้จุดเดียวจะแก้ได้ถึงสองส่วน แก้โค้ดให้ได้ผลลัพธ์:

Student: Alice
Grade: 85
Passed: True
# Bug 1: Something wrong with the variable name
student_name = 'Alice'
print(f'Student: {student_Name}')
# Bug 2: Something wrong with the type
grade = '85'
print(f'Grade: {grade + 0}')
# Bug 3: Something wrong with the comparison
passed = grade >= 60
print(f'Passed: {passed}')

สรุป: ข้อความแจ้งข้อผิดพลาดใน Python

นี่คือตารางสรุปข้อผิดพลาดที่พบบ่อยที่สุดใน Python:

ข้อผิดพลาดความหมายสิ่งแรกที่ควรตรวจ
SyntaxErrorโครงสร้างโค้ดผิดโคลอน วงเล็บ เครื่องหมายคำพูดที่หายไป
NameErrorไม่รู้จักตัวแปรการสะกด ลำดับการสร้างตัวแปร
TypeErrorชนิดข้อมูลผิดตรวจชนิดด้วย type()
IndexErrorดัชนีลิสต์ไม่ถูกต้องความยาวลิสต์ ดัชนีเริ่มที่ 0
KeyErrorคีย์ดิกชันนารีไม่ถูกต้องใช้ .get() พร้อมค่าเริ่มต้น
ValueErrorค่าผิดตรวจสอบก่อนแปลงชนิด

กฎทองของการดีบัก:

  • อ่าน บรรทัดสุดท้าย ของ traceback ก่อนเสมอ
  • ดู หมายเลขบรรทัด ที่ Python บอก (และบรรทัดก่อนหน้านั้น)
  • ใช้ print(type(x), x) ตรวจดูตัวแปรที่น่าสงสัย
  • ข้อความแจ้งข้อผิดพลาดคือผู้ช่วย ไม่ใช่ศัตรู มันบอกคุณตรงๆ ว่าอะไรผิดพลาด
  • เรียนอะไรต่อ

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

    บทเรียนที่เกี่ยวข้อง

    บทเรียนนี้มีประโยชน์หรือไม่