من الأخطاء التي تظهر كثيرًا أثناء تعلم بايثون خطأ:
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} ببساطة: الخطأ يظهر عندما تتعامل مع متغير كأنه قائمة أو نص وتستخدم معه []، لكنه في الحقيقة رقم أو قيمة لا تدعم الفهرسة.
ما معنى 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رقم صحيح مثل123floatرقم عشري مثل3.14None- الدالة نفسها إذا كتبت اسمها بدون أقواس الاستدعاء
()
{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
كيف تعرف نوع المتغير قبل استخدام الفهرسة؟
من أفضل الطرق لفهم سبب الخطأ استخدام الدالة 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
- اذهب إلى السطر الذي يظهر في رسالة الخطأ.
- ابحث عن المتغير الذي استخدمت معه
[]. - اطبع نوع المتغير باستخدام
type(). - إذا كان رقمًا، لا تستخدم معه الفهرسة مباشرة.
- إذا كان
None، تأكد أن الدالة ترجع قيمة باستخدامreturn. - إذا كان دالة، تأكد أنك كتبت الأقواس
()عند الاستدعاء. - إذا كنت تحتاج إلى فهرسة، استخدم نوعًا مناسبًا مثل List أو String أو Tuple.
أخطاء مرتبطة قد تواجهك
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] للحصول على أول حرف.
روابط مهمة من بايثون العرب
- أساسيات بايثون 16: شرح القوائم Lists في Python للمبتدئين بالأمثلة
- أساسيات بايثون 17: شرح Tuples في Python والفرق بينها وبين Lists
- حل مشكلة can only concatenate str not int to str في بايثون
- حل مشكلة ValueError invalid literal for int في بايثون
- أساسيات بايثون 14: شرح return في الدوال
مصدر خارجي مفيد
الخلاصة
خطأ TypeError: object is not subscriptable يظهر عندما تستخدم الأقواس المربعة [] مع كائن لا يدعم الفهرسة، مثل رقم صحيح، رقم عشري، قيمة None، أو دالة لم يتم استدعاؤها بشكل صحيح.
لحل المشكلة، افحص نوع المتغير باستخدام type()، وتأكد أنك تستخدم الفهرسة فقط مع أنواع مناسبة مثل List أو String أو Tuple. وإذا كانت المشكلة من دالة، فتأكد من وجود return واستدعاء الدالة بالأقواس.
{alertSuccess} القاعدة الذهبية: قبل استخدام [] اسأل نفسك: هل هذا المتغير قائمة أو نص أو Tuple أو قاموس؟ إذا لم يكن كذلك، فغالبًا سيظهر الخطأ.