مشكلة وحل 11: حل خطأ TypeError object is not subscriptable في بايثون

مشكلة وحل 11 حل خطأ TypeError object is not subscriptable في بايثون للمبتدئين

من الأخطاء التي تظهر كثيرًا أثناء تعلم بايثون خطأ:

TypeError: 'int' object is not subscriptable

وقد يظهر الخطأ بصيغ أخرى حسب نوع المتغير المستخدم، مثل:

TypeError: 'float' object is not subscriptable
TypeError: 'function' object is not subscriptable
TypeError: 'NoneType' object is not subscriptable

هذا الخطأ يحدث غالبًا عندما تستخدم الأقواس المربعة [] مع متغير لا يدعم الفهرسة. مثلًا: تحاول كتابة number[0] مع رقم عادي، أو تستخدم result[0] بينما المتغير لا يحتوي على قائمة أو نص أو Tuple.

في هذا الدرس من سلسلة مشكلة وحل على بايثون العرب سنشرح معنى خطأ object is not subscriptable في Python، ولماذا يظهر، وكيف تحله خطوة بخطوة مع أمثلة عملية واضحة للمبتدئين.

{getToc} $title={محتوى المقال}

{alertInfo} ببساطة: الخطأ يظهر عندما تتعامل مع متغير كأنه قائمة أو نص وتستخدم معه []، لكنه في الحقيقة رقم أو قيمة لا تدعم الفهرسة.

مثال يوضح ظهور خطأ TypeError object is not subscriptable عند استخدام الفهرسة على int في بايثون

ما معنى object is not subscriptable في بايثون؟

كلمة subscriptable في بايثون تعني أن الكائن يسمح لك باستخدام الأقواس المربعة [] للوصول إلى جزء منه، مثل عنصر داخل قائمة أو حرف داخل نص.

مثال: القائمة List تدعم الفهرسة:

names = ["Ali", "Sara", "Omar"]

print(names[0])

الناتج:

Ali

والنص String يدعم الفهرسة أيضًا:

word = "Python"

print(word[0])

الناتج:

P

أما الرقم العادي فلا يدعم الفهرسة:

number = 123

print(number[0])

هنا يظهر الخطأ لأن number هو رقم من نوع int، وليس قائمة أو نصًا يمكن الوصول إلى جزء منه باستخدام [].

لماذا يظهر خطأ TypeError object is not subscriptable؟

يظهر هذا الخطأ عندما تضع [] بعد كائن لا يدعم الوصول بالفهرس. لذلك الحل يبدأ دائمًا من معرفة نوع المتغير الذي استخدمت معه الأقواس المربعة.

أمثلة على كائنات تدعم الفهرسة:

  • list مثل [10, 20, 30]
  • string مثل "Python"
  • tuple مثل (10, 20, 30)
  • dictionary باستخدام المفاتيح مثل user["name"]

وأمثلة على كائنات غالبًا لا تدعم الفهرسة:

  • int رقم صحيح مثل 123
  • float رقم عشري مثل 3.14
  • None
  • الدالة نفسها إذا كتبت اسمها بدون أقواس الاستدعاء ()
مقارنة توضح الفرق بين الكائنات التي تدعم الفهرسة مثل List و String والكائنات التي لا تدعمها مثل int
{alertWarning} وجود الأقواس [] لا يعني أنها تصلح مع كل شيء. استخدمها فقط مع كائنات تدعم الفهرسة أو المفاتيح.

مثال 1: استخدام الفهرسة مع رقم int

هذا المثال من أشهر أسباب الخطأ:

age = 25

print(age[0])

سيظهر خطأ مثل:

TypeError: 'int' object is not subscriptable

سبب الخطأ

المتغير age يحتوي على رقم صحيح، والرقم لا يحتوي على عناصر داخلية يمكن الوصول إليها باستخدام [0].

الحل

إذا كنت تريد طباعة الرقم، اطبعه مباشرة:

age = 25

print(age)

أما إذا كنت تريد الوصول إلى أول خانة داخل العدد، حوّل الرقم إلى نص أولًا:

number = 123

text_number = str(number)

print(text_number[0])

الناتج:

1
{alertInfo} إذا أردت التعامل مع خانات الرقم كأحرف، حول الرقم إلى نص باستخدام str().

مثال 2: استخدام الفهرسة مع float

الرقم العشري أيضًا لا يدعم الفهرسة مباشرة.

price = 19.99

print(price[0])

سيظهر خطأ:

TypeError: 'float' object is not subscriptable

الحل

إذا أردت طباعة السعر، اطبعه مباشرة:

price = 19.99

print(price)

وإذا أردت التعامل معه كنص:

price = 19.99

price_text = str(price)

print(price_text[0])

الناتج:

1

مثال 3: المتغير كان قائمة ثم تغير إلى رقم

أحيانًا يكون سبب الخطأ أنك تبدأ بمتغير يحتوي على قائمة، ثم تغيّر قيمته لاحقًا إلى رقم بدون أن تنتبه.

scores = [90, 80, 70]

scores = 100

print(scores[0])

سيظهر الخطأ لأن scores لم تعد قائمة، بل أصبحت رقمًا.

الحل

لا تستخدم نفس اسم المتغير لمعنيين مختلفين:

scores = [90, 80, 70]

new_score = 100

print(scores[0])

الناتج:

90
{alertSuccess} اختر أسماء متغيرات واضحة، ولا تجعل نفس المتغير مرة قائمة ومرة رقمًا إلا إذا كنت تقصد ذلك فعلًا.

مثال 4: الدالة ترجع None ثم تحاول استخدام []

أحيانًا الدالة لا ترجع قيمة، فتكون النتيجة None. وبعد ذلك تحاول استخدام الفهرسة عليها.

def get_names():
    names = ["Ali", "Sara", "Omar"]

result = get_names()

print(result[0])

سيظهر خطأ:

TypeError: 'NoneType' object is not subscriptable

سبب الخطأ

الدالة get_names() أنشأت قائمة داخلها، لكنها لم تستخدم return لإرجاعها. لذلك قيمة result أصبحت None.

الحل

أضف return داخل الدالة:

def get_names():
    names = ["Ali", "Sara", "Omar"]
    return names

result = get_names()

print(result[0])

الناتج:

Ali

مثال 5: نسيان استدعاء الدالة بالأقواس

قد تكتب اسم الدالة بدون أقواس، ثم تحاول استخدام الفهرسة على الدالة نفسها.

def get_numbers():
    return [10, 20, 30]

result = get_numbers

print(result[0])

قد يظهر خطأ لأن result يشير إلى الدالة نفسها، وليس إلى ناتج الدالة.

الحل

استدعِ الدالة بالأقواس:

def get_numbers():
    return [10, 20, 30]

result = get_numbers()

print(result[0])

الناتج:

10
أمثلة توضح حل خطأ object is not subscriptable في Python بتصحيح نوع المتغير قبل استخدام index

كيف تعرف نوع المتغير قبل استخدام الفهرسة؟

من أفضل الطرق لفهم سبب الخطأ استخدام الدالة type() لمعرفة نوع المتغير قبل استخدام [].

value = 123

print(type(value))

الناتج:

<class 'int'>

إذا ظهر لك int أو float أو NoneType، فلا تستخدم الفهرسة [] إلا إذا حولت القيمة إلى نوع مناسب.

حل سريع حسب نوع الخطأ

رسالة الخطأ السبب غالبًا الحل
'int' object is not subscriptable استخدام [] مع رقم صحيح اطبع الرقم مباشرة أو حوله إلى نص باستخدام str()
'float' object is not subscriptable استخدام [] مع رقم عشري اطبعه مباشرة أو حوله إلى نص إذا احتجت
'NoneType' object is not subscriptable الدالة لم ترجع قيمة أضف return أو افحص النتيجة قبل استخدام []
'function' object is not subscriptable نسيت أقواس استدعاء الدالة اكتب function_name() بدل function_name

مثال عملي كامل لتجنب الخطأ

لنفترض أنك تريد جلب أول اسم من قائمة أسماء. الطريقة الصحيحة أن تتأكد أن الناتج فعلًا قائمة قبل استخدام الفهرسة:

def get_students():
    return ["Ali", "Sara", "Omar"]

students = get_students()

if isinstance(students, list):
    print(students[0])
else:
    print("القيمة ليست قائمة")

الناتج:

Ali

هنا استخدمنا isinstance() للتأكد أن المتغير قائمة قبل استخدام الفهرسة.

ما الفرق بين [] و () في هذا الخطأ؟

الأقواس المربعة [] تستخدم غالبًا للوصول إلى عنصر داخل قائمة أو نص أو Tuple أو قيمة داخل Dictionary. أما الأقواس الدائرية () فتستخدم لاستدعاء الدوال.

مثال فهرسة صحيح:

names = ["Ali", "Sara"]

print(names[0])

ومثال استدعاء دالة صحيح:

def get_name():
    return "Ali"

print(get_name())
{alertWarning} لا تخلط بين [] للفهرسة و () لاستدعاء الدوال، فهذا سبب شائع لأخطاء كثيرة في Python.

خطوات حل خطأ object is not subscriptable

  1. اذهب إلى السطر الذي يظهر في رسالة الخطأ.
  2. ابحث عن المتغير الذي استخدمت معه [].
  3. اطبع نوع المتغير باستخدام type().
  4. إذا كان رقمًا، لا تستخدم معه الفهرسة مباشرة.
  5. إذا كان None، تأكد أن الدالة ترجع قيمة باستخدام return.
  6. إذا كان دالة، تأكد أنك كتبت الأقواس () عند الاستدعاء.
  7. إذا كنت تحتاج إلى فهرسة، استخدم نوعًا مناسبًا مثل List أو String أو Tuple.
ملخص أسباب وحلول خطأ TypeError object is not subscriptable في بايثون للمبتدئين

أخطاء مرتبطة قد تواجهك

IndexError

يظهر خطأ IndexError عندما يكون الكائن يدعم الفهرسة، لكنك طلبت فهرسًا غير موجود.

names = ["Ali", "Sara"]

print(names[5])

KeyError

يظهر خطأ KeyError غالبًا مع القواميس عندما تطلب مفتاحًا غير موجود.

user = {"name": "Ali"}

print(user["age"])

TypeError

الخطأ الذي نشرحه في هذا المقال هو نوع من TypeError، لأنه يحدث بسبب استخدام عملية غير مناسبة مع نوع بيانات معين.

تدريب سريع

جرّب الكود التالي، ثم غيّر قيمة المتغير value مرة إلى قائمة، ومرة إلى رقم، ومرة إلى نص. الهدف من التدريب أن تفهم متى يمكن استخدام [] ومتى لا يمكن استخدامها.

value = ["Python", "HTML", "CSS"]

print(type(value))
print(value[0])

أسئلة شائعة

ما معنى TypeError object is not subscriptable؟

يعني أنك استخدمت الأقواس المربعة [] مع كائن لا يدعم الفهرسة، مثل رقم أو قيمة None.

كيف أحل خطأ int object is not subscriptable؟

لا تستخدم [] مع الرقم مباشرة. اطبعه كما هو، أو حوله إلى نص باستخدام str() إذا أردت الوصول إلى خاناته.

ما سبب خطأ NoneType object is not subscriptable؟

غالبًا لديك دالة لم ترجع قيمة باستخدام return، لذلك الناتج أصبح None ثم حاولت استخدام [] عليه.

هل القائمة List تدعم subscriptable؟

نعم، القائمة تدعم الفهرسة، ويمكنك استخدام my_list[0] للوصول إلى أول عنصر.

هل النص String يدعم الفهرسة؟

نعم، النص يدعم الفهرسة، ويمكنك مثلًا استخدام word[0] للحصول على أول حرف.

روابط مهمة من بايثون العرب

مصدر خارجي مفيد

الخلاصة

خطأ TypeError: object is not subscriptable يظهر عندما تستخدم الأقواس المربعة [] مع كائن لا يدعم الفهرسة، مثل رقم صحيح، رقم عشري، قيمة None، أو دالة لم يتم استدعاؤها بشكل صحيح.

لحل المشكلة، افحص نوع المتغير باستخدام type()، وتأكد أنك تستخدم الفهرسة فقط مع أنواع مناسبة مثل List أو String أو Tuple. وإذا كانت المشكلة من دالة، فتأكد من وجود return واستدعاء الدالة بالأقواس.

{alertSuccess} القاعدة الذهبية: قبل استخدام [] اسأل نفسك: هل هذا المتغير قائمة أو نص أو Tuple أو قاموس؟ إذا لم يكن كذلك، فغالبًا سيظهر الخطأ.

إرسال تعليق

أحدث أقدم