ด้วย Python คุณสามารถวนซ้ำ (iterate) ผ่านออบเจ็กต์ได้ก็ต่อเมื่อออบเจ็กต์นั้นมีค่า เนื่องจากออบเจ็กต์ที่วนซ้ำได้มีรายการถัดไป (next item) ซึ่งสามารถเข้าถึงได้ก็ต่อเมื่อค่าของมันไม่เท่ากับ None หากคุณพยายามวนซ้ำผ่านออบเจ็กต์ None คุณจะเจอข้อผิดพลาด TypeError: 'NoneType' object is not iterable
ในคู่มือนี้ เราพูดถึงว่าข้อผิดพลาดนี้หมายถึงอะไรและทำไมคุณอาจพบมัน เราจะเดินทางผ่านตัวอย่างเพื่อช่วยคุณแก้ไขวิธีแก้ไขข้อผิดพลาด Python ทั่วไปนี้
TypeError: 'NoneType' object is not iterable
สำหรับออบเจ็กต์ที่จะวนซ้ำได้ มันต้องมีค่า ค่า None ไม่สามารถวนซ้ำได้เพราะมันไม่มีออบเจ็กต์ใดๆ None แทนค่า null
มีความแตกต่างระหว่างออบเจ็กต์ None และ iterable ว่าง ข้อผิดพลาดนี้ไม่ถูกยกขึ้นหากคุณมีลิสต์ว่างหรือสตริงว่าง
นี่เป็นเพราะลิสต์และสตริงมีชนิดข้อมูลที่วนซ้ำได้ เมื่อ Python interpreter พบลิสต์ว่าง มันไม่วนซ้ำผ่านมันเพราะไม่มีค่า Python ไม่สามารถวนซ้ำผ่านค่า None ได้ ดังนั้น interpreter จึงคืนค่าข้อผิดพลาด
ข้อผิดพลาดนี้พบบ่อยเมื่อคุณประกาศฟังก์ชันและลืมคืนค่า
สถานการณ์ตัวอย่าง
มาเขียนโปรแกรมที่รับรายชื่อนักเรียนและกรองเฉพาะที่ขึ้นต้นด้วย "E" เราจะพิมพ์ค่าเหล่านั้นไปยังคอนโซล
เริ่มต้นด้วยการกำหนดฟังก์ชันที่กรองชื่อนักเรียน:
def filter_students(class_names): new_class_names = [] for c in class_names: if c.startswith("E"): new_class_names.append(c) ฟังก์ชันนี้วนซ้ำผ่านทุกรายการในรายการ "class_names" โดยใช้ลูป for สำหรับแต่ละรายการ ลูปของเราตรวจสอบว่ารายการนั้นขึ้นต้นด้วยตัวอักษร "E" หรือไม่ หากใช่ ชื่อนั้นจะถูกเพิ่มเข้าไปในรายการ "new_class_names"
ต่อไป เขียนฟังก์ชันที่ผ่านรายการใหม่ของเราและพิมพ์แต่ละค่าไปยังคอนโซล:
def show_students(class_names): for c in class_names: print(c)
ที่นี่ เราประกาศรายการนักเรียนที่โปรแกรมของเราควรค้นหา เราส่งรายการนักเรียนนี้ผ่านฟังก์ชัน filter_students ของเรา:
students = ["Elena", "Peter", "Chad", "Sam"] students_e_name = filter_students(students)
โค้ดนี้ execute ฟังก์ชัน filter_students ซึ่งหานักเรียนทั้งหมดที่ชื่อขึ้นต้นด้วย "E" รายการนักเรียนที่ชื่อขึ้นต้นด้วย "E" ถูกเรียกว่า students_e_name ต่อไป เราเรียกฟังก์ชัน show_students ของเราเพื่อแสดงรายการนักเรียนใหม่:
show_students(students_e_name)
มารันโค้ดของเราและ看看发生什么:
Traceback (most recent call last): File "main.py", line 14, in <module> show_students(students_e_name) File "main.py", line 8, in show_students for c in class_names: TypeError: 'NoneType' object is not iterable
โค้ดของเราคืนค่าข้อความข้อผิดพลาด
วิธีแก้ไข
เมื่อเราพยายามวนซ้ำผ่านตัวแปร class_names ในฟังก์ชัน show_students โค้ดของเราตรวจพบค่า None และยกข้อผิดพลาดขึ้น นี่เป็นเพราะค่าที่เราส่งผ่านเป็น "class_names" เป็น None
ข้อผิดพลาดนี้เกิดเพราะฟังก์ชัน filter_students ของเราไม่คืนค่า เมื่อเรากำหนดผลลัพธ์ของฟังก์ชัน filter_students ให้กับตัวแปร students_e_name ค่า None ถูกตั้งค่า
เพื่อแก้ไขข้อผิดพลาดนี้ เราต้องคืนค่าในฟังก์ชัน filter_students ของเรา:
def filter_students(class_names): new_class_names = [] for c in class_names: if c.startswith("E"): new_class_names.append(c) # We have added a return statement here return new_class_names def show_students(class_names): for c in class_names: print(c) students = ["Elena", "Peter", "Chad", "Sam"] students_e_name = filter_students(students) show_students(students_e_name) โค้ดนี้คืนค่าของ new_class_names กลับไปยังโปรแกรมหลัก
มารันโค้ดของเราเพื่อดูว่ามันทำงานหรือไม่:
Elena
โค้ดของเราตอนนี้พิมพ์ชื่อนักเรียนที่ขึ้นต้นด้วย "E" สำเร็จแล้ว
การหลีกเลี่ยงข้อยกเว้น NoneType
ทางเทคนิค คุณสามารถหลีกเลี่ยงข้อยกเว้น NoneType ได้โดยตรวจสอบว่าค่าเท่ากับ None ก่อนที่คุณจะวนซ้ำผ่านค่านั้น พิจารณาโค้ดต่อไปนี้:
def filter_students(class_names): new_class_names = [] for c in class_names: if c.startswith("E"): new_class_names.append(c) return new_class_names def show_students(class_names): if class_names is not None: for c in class_names: print(c) students = ["Elena", "Peter", "Chad", "Sam"] students_e_name = filter_students(students) show_students(students_e_name) ฟังก์ชัน "show_students()" execute สำเร็จเพราะเราตรวจสอบว่า class_names เป็นค่า None ก่อนที่เราจะพยายามวนซ้ำผ่านมัน นี่ไม่ใช่แนวทางปฏิบัติที่ดีในส่วนใหญ่ เพราะสาเหตุของข้อผิดพลาด NoneType อาจเป็นปัญหาที่อื่นในโค้ดของคุณ
หากเราเพิ่มการตรวจสอบ "is not None" เข้าไปในโปรแกรมเต็มของเรา เราจะไม่รู้ว่าเราพลาดคำสั่ง return ในฟังก์ชันอื่น นั่นคือเหตุผลที่หากคุณเห็นข้อผิดพลาดนี้ คุณควรยอมรับข้อยกเว้นแทนที่จะจัดการมันโดยใช้การตรวจสอบ "is not None"
สรุป
ข้อผิดพลาด TypeError: 'NoneType' object is not iterable ถูกยกขึ้นเมื่อคุณพยายามวนซ้ำผ่านออบเจ็กต์ที่ค่าของมันเท่ากับ None
เพื่อแก้ไขข้อผิดพลาดนี้ ตรวจสอบให้แน่ใจว่าค่าใดๆ ที่คุณพยายามวนซ้ำได้ถูกกำหนดออบเจ็กต์ที่วนซ้ำได้ เช่น สตริงหรือลิสต์ ในตัวอย่างของเรา เราลืมเพิ่มคำสั่ง "return" ให้กับฟังก์ชัน นี่ทำให้ฟังก์ชันคืนค่า None แทนที่จะเป็นลิสต์
ตอนนี้คุณพร้อมที่จะแก้ไขข้อผิดพลาด Python ทั่วไปนี้ในโค้ดของคุณเองแล้ว