ไม่เหมือนกับออบเจ็กต์ที่วนซ้ำได้ (iterable objects) คุณไม่สามารถเข้าถึงค่าจากฟังก์ชันโดยใช้ไวยากรณ์การจัดดัชนี (indexing syntax) ได้
แม้ฟังก์ชันจะคืนค่าออบเจ็กต์ที่วนซ้ำได้ คุณต้องกำหนดการตอบสนองจากฟังก์ชันให้กับตัวแปรก่อนเข้าถึงค่าของมัน มิฉะนั้น คุณจะเจอข้อผิดพลาด "TypeError: 'function' object is not subscriptable"
ในคู่มือนี้ เราพูดถึงว่าข้อผิดพลาดนี้หมายถึงอะไร เราจะเดินทางผ่านสองตัวอย่างของข้อผิดพลาดนี้ เพื่อคุณสามารถหาวิธีแก้ไขในโค้ดของคุณได้
TypeError: 'function' object is not subscriptable
ออบเจ็กต์ที่วนซ้ำได้ เช่น ลิสต์และสตริง สามารถเข้าถึงได้โดยใช้สัญกรณ์การจัดดัชนี (indexing notation) นี่ให้คุณเข้าถึงรายการเดี่ยว หรือช่วงของรายการ จากออบเจ็กต์ที่วนซ้ำได้
พิจารณาโค้ดต่อไปนี้:
grades = ["A", "A", "B"] print(grades[0])
ค่าที่ตำแหน่งดัชนี 0 คือ A ดังนั้น โค้ดของเราคืนค่า "A" ไวยากรณ์นี้ไม่ทำงานบนฟังก์ชัน เนื่องจากฟังก์ชันไม่ใช่ออบเจ็กต์ที่วนซ้ำได้ ฟังก์ชันสามารถคืนค่าออบเจ็กต์ที่วนซ้ำได้ก็ต่อเมื่อถูกเรียก
ข้อผิดพลาด "TypeError: 'function' object is not subscriptable" เกิดขึ้นเมื่อคุณพยายามเข้าถึงฟังก์ชันาว่ามันเป็นออบเจ็กต์ที่วนซ้ำได้
ข้อผิดพลาดนี้พบบ่อยในสองสถานการณ์:
- เมื่อคุณกำหนดฟังก์ชันชื่อเดียวกับออบเจ็กต์ที่วนซ้ำได้
- เมื่อคุณพยายามเข้าถึงค่าจากฟังก์ชันาว่าฟังก์ชันนั้นวนซ้ำได้
มา分析ทั้งสองสถานการณ์นี้
สถานการณ์ #1: ฟังก์ชันชื่อเดียวกับ Iterable
สร้างโปรแกรมที่พิมพ์ข้อมูลเกี่ยวกับนักเรียนที่โรงเรียน เราเริ่มต้นด้วยการกำหนดดิกชันนารีพร้อมข้อมูลนักเรียนและคะแนนสอบล่าสุด:
student = { "name": "Holly", "latest_test_score": "B", "class": "Sixth Grade" } ดิกชันนารีของเราประกอบด้วยสามกุญแจและสามค่า กุญแจหนึ่งแทนชื่อนักเรียน กุญแจหนึ่งแทนคะแนนที่นักเรียนได้รับในการสอบล่าสุด กุญแจหนึ่งแทนชั้นที่นักเรียนอยู่
ต่อไป เราจะกำหนดฟังก์ชันที่พิมพ์ค่าเหล่านี้ไปยังคอนโซล:
def student(pupil): print("Name: " + pupil["name"]) print("Latest Test Score: " + pupil["latest_test_score"]) print("Class: " + pupil["class"]) โค้ดของเราพิมพ์ค่าสามค่าในดิกชันนารี "pupil" ไปยังคอนโซล ดิกชันนารี "pupil" ถูกส่งเป็นอาร์กิวเมนต์เข้าไปในฟังก์ชัน student()
มาเรียกฟังก์ชันของเราและส่งดิกชันนารี "student" เป็นพารามิเตอร์:
student(student)
โค้ด Python ของเราโยนข้อผิดพลาด:
Traceback (most recent call last): File "main.py", line 8, in <module> student(student) File "main.py", line 4, in student print("Name: " + pupil["name"]) TypeError: 'function' object is not subscriptable ข้อผิดพลาดนี้เกิดเพราะเรามีฟังก์ชันและ iterable ชื่อเดียวกัน "student" ถูกประกาศเป็นดิกชันนารีก่อน เราจึงกำหนดฟังก์ชันชื่อเดียวกัน นี่ทำให้ "student" กลายเป็นฟังก์ชันแทนที่จะเป็นดิกชันนารี
เมื่อเราส่ง "student" เป็นพารามิเตอร์เข้าไปในฟังก์ชัน student() เรากำลังส่งฟังก์ชันที่ชื่อ "student"
เราแก้ปัญหานี้โดยเปลี่ยนชื่อฟังก์ชัน student ของเรา:
def show_student_details(pupil): print("Name: " + pupil["name"]) print("Latest Test Score: " + pupil["latest_test_score"]) print("Class: " + pupil["class"]) show_student_details(student) เราเปลี่ยนชื่อฟังก์ชันเป็น "show_student_details" มารันโค้ดของเราและ看看发生什么:
Name: Holly Latest Test Score: B Class: Sixth Grade
โค้ดของเราพิมพ์ข้อมูลเกี่ยวกับนักเรียนของเราไปยังคอนโซลสำเร็จแล้ว
สถานการณ์ #2: การเข้าถึงฟังก์ชันโดยใช้ Indexing
เขียนโปรแกรมที่กรองรายการบันทึกนักเรียนและแสดงเฉพาะที่นักเรียนได้เกรด A ในการสอบล่าสุด
เราจะเริ่มต้นด้วยการกำหนดอาร์เรย์ของนักเรียน:
students = [ { "name": "Holly", "grade": "B" }, { "name": "Samantha", "grade": "A" }, { "name": "Ian", "grade": "A" } ] รายการนักเรียนของเราประกอบด้วยสามดิกชันนารี แต่ละดิกชันนารีประกอบด้วยชื่อนักเรียนและเกรดที่พวกเขาได้รับในการสอบล่าสุด
ต่อไป กำหนดฟังก์ชันที่คืนค่ารายการนักเรียนที่ได้เกรด A:
def get_a_grade_students(pupils): a_grade_students = [] for p in pupils: if p["grade"] == "A": a_grade_students.append(p) print(a_grade_students) return a_grade_students
ฟังก์ชันรับรายการนักเรียนชื่อ "pupils" ฟังก์ชันของเราวนซ้ำผ่านรายการนั้นโดยใช้ลูป for หากนักเรียนคนใดได้เกรด "A" บันทึกของพวกเขาจะถูกเพิ่มเข้าไปในรายการ "a_grade_students" มิฉะนั้น ไม่มีอะไรเกิดขึ้น
เมื่อค้นหานักเรียนทั้งหมดแล้ว โค้ดของเราพิมพ์รายการนักเรียนที่ได้เกรด "A" และคืนค่ารายการนั้นไปยังโปรแกรมหลัก
เราต้องการดึงนักเรียนคนแรกที่ได้เกรด "A" เพื่อทำเช่นนี้ เราเรียกฟังก์ชันของเราและใช้ไวยากรณ์การจัดดัชนีเพื่อดึงบันทึกของนักเรียนคนแรก:
first = get_a_grade_students[0] print(first)
รันโค้ดของเรา:
Traceback (most recent call last): File "main.py", line 16, in <module> first = get_a_grade_students[0] TypeError: 'function' object is not subscriptable
โค้ดของเราคืนค่าข้อผิดพลาด เรากำลังพยายามเข้าถึงค่าจากฟังก์ชัน "get_a_grade_students" โดยไม่ได้เรียกฟังก์ชันก่อน
เพื่อแก้ปัญหานี้ เราควรเรียกฟังก์ชันของเราก่อนที่จะพยายามดึงค่าจากมัน:
a_grades = get_a_grade_students(students) first = a_grades[0] print(first)
ก่อนอื่น เราเรียกฟังก์ชัน get_a_grade_students() และระบุลิสต์นักเรียนเป็นพารามิเตอร์ ต่อไป เราใช้การจัดดัชนีเพื่อดึงบันทึกที่ตำแหน่งดัชนี 0 จากรายการที่ฟังก์ชัน get_a_grade_students() คืนค่า สุดท้าย เราพิมพ์บันทึกนั้นไปยังคอนโซล
มา execute โค้ดของเรา:
[{'name': 'Samantha', 'grade': 'A'}, {'name': 'Ian', 'grade': 'A'}] {'name': 'Samantha', 'grade': 'A'} โค้ดของเราก่อนหน้าพิมพ์รายการนักเรียนทั้งหมดที่ได้เกรด "A" ต่อไป โค้ดของเราพิมพ์นักเรียนคนแรกในรายการที่ได้เกรด "A" นักเรียนคนนั้นคือ Samantha ในกรณีนี้
สรุป
ข้อผิดพลาด "TypeError: 'function' object is not subscriptable" ถูกยกขึ้นเมื่อคุณพยายามเข้าถึงรายการจากฟังก์ชันาว่าฟังก์ชันเป็นออบเจ็กต์ที่วนซ้ำได้ เช่น สตริงหรือลิสต์
เพื่อแก้ไขข้อผิดพลาดนี้ ตรวจสอบก่อนว่าคุณไม่ได้เขียนทับตัวแปรที่จัดเก็บค่าโดยการประกาศฟังก์ชันหลังจากที่คุณประกาศตัวแปร ต่อไป ตรวจสอบให้แน่ใจว่าคุณเรียกฟังก์ชันก่อนที่คุณจะพยายามเข้าถึงค่าที่มันคืนค่า
ตอนนี้คุณพร้อมที่จะแก้ไขข้อผิดพลาด Python ทั่วไปนี้อย่างนักเขียนโค้ดมืออาชีพแล้ว!