قد تكتب برنامجًا بسيطًا في Python لجمع أسماء أو كلمات، ثم تحاول إضافة قيمة جديدة باستخدام append()، فتظهر لك رسالة تشبه الآتي:
AttributeError: 'str' object has no attribute 'append'
هذا الخطأ شائع جدًا عند المبتدئين لأنه لا يعني أن append() نفسها لا تعمل، بل يعني أنك حاولت استخدامها مع نص String بينما هي دالة خاصة بالقوائم List. في هذا الدرس ستفهم سبب المشكلة، وكيف تعرف نوع المتغير قبل استخدامه، ومتى تستخدم append() ومتى تستخدم + أو join().
{alertInfo} الفكرة ببساطة: الدالةappend()تضيف عنصرًا إلى نهايةList، لكنها لا تعمل معString. إذا كانت القيمة نصًا، استخدم دمج النصوص أو حوّل طريقة عملك إلى قائمة ثم استخدمjoin()عند الحاجة.
{getToc} $title={محتوى المقال}
شكل الخطأ في Python
قد تختلف الرسالة حسب اسم المتغير، لكن الجزء المهم منها يكون عادة:
AttributeError: 'str' object has no attribute 'append'
لنقسمها إلى أجزاء بسيطة:
| جزء الرسالة | معناه |
|---|---|
AttributeError |
استخدمت خاصية أو دالة غير موجودة لهذا النوع من البيانات. |
'str' |
القيمة الحالية للمتغير نص من نوع String. |
object has no attribute 'append' |
النص لا يملك دالة باسم append(). |
إذن الحل لا يبدأ من حذف append() عشوائيًا؛ بل من الإجابة عن سؤال واحد: هل المتغير الذي أستخدم معه append هو List فعلًا أم String؟
مثال بسيط يسبب الخطأ
انظر إلى هذا الكود:
name = "Ali"
name.append(" Ahmed")
print(name)
سيظهر الخطأ لأن name يحتوي على نص واحد، والنص لا يملك دالة append().
إذا كان المطلوب هو دمج نصين، استخدم + أو f-string:
name = "Ali"
name = name + " Ahmed"
print(name)
Ali Ahmed
لماذا تعمل append مع List ولا تعمل مع String؟
القائمة List مصممة لتخزين عدة عناصر، ويمكن تعديلها بإضافة عناصر أو حذفها أو تغيير ترتيبها. لذلك تحتوي على دوال مثل append() وextend() وremove().
أما النص String فهو قيمة نصية واحدة. عندما تريد تغييره، تنشئ Python نصًا جديدًا بدل تعديل النص نفسه في مكانه. لهذا لا تجد داخله append().
| النوع | مثال | هل append تعمل؟ | الاستخدام المناسب |
|---|---|---|---|
str |
"Python" |
لا | دمج النصوص باستخدام + أو f-string أو join(). |
list |
["Python", "Java"] |
نعم | إضافة عنصر جديد إلى نهاية القائمة. |
توثق Python أن list.append(value) تضيف قيمة إلى نهاية القائمة، وهذا يوضح أن append() مرتبطة بالقوائم وليست دالة نصية.
الحل الأول: استخدم List عندما تريد جمع عناصر متعددة
إذا كان هدفك هو تخزين أكثر من اسم أو أكثر من كلمة، أنشئ قائمة من البداية بدل نص واحد:
names = []
names.append("Ali")
names.append("Sara")
names.append("Omar")
print(names)
['Ali', 'Sara', 'Omar']
هنا تعمل append() لأن names قائمة فعلًا، وليست نصًا.
الحل الثاني: لا تخزن نتيجة input داخل متغير تتوقع أنه List
من أكثر الأسباب العملية للخطأ أن input() ترجع نصًا دائمًا. حتى لو كتب المستخدم كلمة تبدو كعنصر من قائمة، ستظل النتيجة من نوع str.
مثال خاطئ:
items = input("اكتب عنصرًا: ")
items.append("Python")
إذا كتب المستخدم Book، تصبح قيمة items هي النص "Book"، ولذلك يظهر الخطأ عند السطر الثاني.
الحل أن تحتفظ بقائمة منفصلة، ثم تضيف إليها الإدخال:
items = []
new_item = input("اكتب عنصرًا: ").strip()
if new_item:
items.append(new_item)
print(items)
في هذا المثال:
itemsقائمة تستقبل العناصر.new_itemنص يمثل الإدخال الجديد.- نستخدم
strip()لإزالة المسافات الزائدة حول الإدخال. - نضيف النص إلى القائمة باستخدام
append().
الحل الثالث: استخدم split لتحويل النص إلى قائمة
أحيانًا يكتب المستخدم عناصر متعددة في سطر واحد، مثل:
Python,Java,JavaScript
هذه القيمة ما زالت نصًا واحدًا. إذا أردت التعامل معها كقائمة عناصر، استخدم split():
text = "Python,Java,JavaScript"
languages = text.split(",")
languages.append("C++")
print(languages)
['Python', 'Java', 'JavaScript', 'C++']
هنا أعادت split(",") قائمة، ولذلك أصبح استخدام append() صحيحًا.
الحل الرابع: ابنِ النص عبر قائمة ثم استخدم join
إذا كنت تجمع أجزاء كثيرة من النص داخل حلقة، قد يكون من الأنظف أن تضع الأجزاء في قائمة ثم تجمعها في النهاية باستخدام join().
مثال خاطئ:
message = ""
for word in ["تعلم", "Python", "بالعربي"]:
message.append(word)
المتغير message هنا نص فارغ، لذلك ستظهر رسالة AttributeError.
الحل الأفضل:
words = []
for word in ["تعلم", "Python", "بالعربي"]:
words.append(word)
message = " ".join(words)
print(message)
تعلم Python بالعربي
لاحظ الفرق:
wordsقائمة، لذلك يمكن إضافة العناصر إليها.join()تجمع عناصر القائمة في نص واحد في النهاية.
سبب شائع آخر: تغيّر نوع المتغير دون أن تنتبه
قد تبدأ المتغير على أنه قائمة، ثم تعطيه قيمة نصية لاحقًا. عندها تصبح append() غير صالحة:
tasks = []
tasks.append("قراءة الدرس")
tasks = "إكمال التمرين"
tasks.append("مراجعة الكود")
في البداية tasks قائمة، لكن في السطر الثالث تحولت إلى نص. لهذا سيظهر الخطأ في السطر الأخير.
استخدم أسماء واضحة ومختلفة عندما تمثل القيم أشياء مختلفة:
tasks = ["قراءة الدرس"]
current_task = "إكمال التمرين"
tasks.append(current_task)
print(tasks)
كيف تشخص المشكلة بسرعة؟
قبل السطر الذي يظهر فيه الخطأ، اطبع القيمة ونوعها:
print(items)
print(type(items))
إذا ظهر لك:
Book
<class 'str'>
فهذا تأكيد أن items نص وليست قائمة. يمكنك أيضًا استخدام isinstance() عندما تريد التحقق داخل كود حقيقي:
if isinstance(items, list):
items.append("Python")
else:
print("المتغير ليس قائمة.")
أخطاء قريبة من هذه المشكلة
1. استخدام append مع tuple
القيم من نوع tuple لا تملك append() أيضًا، لأنها غير قابلة للتعديل.
colors = ("red", "blue")
colors.append("green")
إذا كنت تحتاج الإضافة، استخدم قائمة بدل tuple:
colors = ["red", "blue"]
colors.append("green")
2. تخزين ناتج append داخل المتغير نفسه
هذه مشكلة مختلفة لكنها شائعة جدًا:
names = ["Ali", "Sara"]
names = names.append("Omar")
print(names)
الدالة append() تعدل القائمة نفسها ولا ترجع قائمة جديدة، لذلك تصبح قيمة names هي None. اكتبها هكذا بدلًا من ذلك:
names = ["Ali", "Sara"]
names.append("Omar")
print(names)
توثق Python أن دوال القوائم التي تعدّل الكائن في مكانه لا ترجع القائمة نفسها؛ بل لا تعيد عنصرًا محددًا.
خطوات الحل السريع
- اقرأ الجزء
'str'داخل رسالة الخطأ؛ فهو يخبرك بنوع المتغير الحالي. - ابحث عن المتغير قبل سطر الخطأ، وتأكد أين حصل على قيمته.
- استخدم
type(variable)إذا لم تكن متأكدًا من نوعه. - إذا كنت تريد تخزين عناصر متعددة، ابدأ بقائمة
[]. - إذا كنت تريد دمج نصوص، استخدم
+أو f-string أوjoin(). - لا تكتب
items = items.append(value).
مثال عملي كامل: برنامج بسيط لجمع أسماء
هذا البرنامج يطلب من المستخدم كتابة أسماء، ويضيف كل اسم إلى قائمة. عندما يضغط المستخدم Enter بدون كتابة اسم، يعرض الأسماء في سطر واحد:
names = []
while True:
name = input("اكتب اسمًا، أو اضغط Enter للانتهاء: ").strip()
if not name:
break
names.append(name)
if names:
print("الأسماء:", ", ".join(names))
else:
print("لم تتم إضافة أسماء.")
في هذا المثال نستخدم كل أداة في مكانها الصحيح:
input()يعيد نصًا واحدًا.namesقائمة تخزن عدة نصوص.append()تضيف كل نص جديد إلى القائمة.join()تجمع القائمة في نص واحد للعرض النهائي.
روابط داخلية مفيدة من بايثون العرب
- سلسلة مشكلة وحل في بايثون
- مشكلة وحل 8: خطأ list object has no attribute lower في Python
- بايثون بالمثال 14: عدّ تكرار العناصر في List باستخدام Python
- بايثون بالمثال 1: حذف التكرار من قائمة في Python
- كورس أساسيات بايثون للمبتدئين
الخلاصة
- رسالة
'str' object has no attribute 'append'تعني أن المتغير نص وليس قائمة. - استخدم
append()لإضافة عنصر إلىListفقط. - استخدم
+أو f-string أوjoin()عندما تتعامل مع النصوص. - تذكر أن
input()ترجعstrدائمًا. - استخدم
type()أوisinstance()لمعرفة نوع المتغير عند تشخيص الخطأ. - لا تخزن ناتج
append()في المتغير نفسه لأنها لا ترجع قائمة جديدة.
{alertSuccess} قاعدة ذهبية: قبل كتابةvariable.append(...)، تأكد أنvariableقائمة فعلًا. وإذا كان نصًا، اسأل: هل أريد دمج نص؟ أم أريد جمع عدة عناصر داخل قائمة؟
مصادر خارجية رسمية للتوسع
- Python Tutorial: Data Structures
- Built-in Types — Python Documentation
- Common String Operations — Python Documentation
أسئلة شائعة
ما معنى str object has no attribute append في Python؟
يعني أن المتغير الذي استخدمت معه append() نص من نوع str، بينما append() دالة خاصة بالقوائم list.
هل يمكن إضافة نص إلى String باستخدام append؟
لا. استخدم دمج النصوص مثل text = text + "new" أو f-string. وإذا كنت تجمع أجزاء كثيرة، ضعها في List ثم استخدم join().
لماذا يظهر الخطأ بعد input؟
لأن input() ترجع نصًا دائمًا، حتى لو أدخل المستخدم رقمًا أو كلمة. أنشئ قائمة منفصلة ثم أضف ناتج input إليها.
هل append ترجع قائمة جديدة؟
لا. الدالة append() تعدل القائمة الحالية في مكانها وترجع None. لذلك لا تكتب items = items.append(value).
كيف أعرف هل المتغير String أو List؟
استخدم print(type(variable)). إذا ظهر <class 'str'> فهو نص، وإذا ظهر <class 'list'> فهو قائمة.



