مشكلة وحل 19: حل خطأ AttributeError: 'str' object has no attribute 'append' في Python

حل خطأ str object has no attribute append في Python للمبتدئين

قد تكتب برنامجًا بسيطًا في 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() مرتبطة بالقوائم وليست دالة نصية.

الفرق بين String وList عند استخدام append في Python

الحل الأول: استخدم 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().
حل خطأ append بعد استخدام input في Python

الحل الثالث: استخدم 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 مع List ثم join لإنشاء نص في Python

سبب شائع آخر: تغيّر نوع المتغير دون أن تنتبه

قد تبدأ المتغير على أنه قائمة، ثم تعطيه قيمة نصية لاحقًا. عندها تصبح 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 أن دوال القوائم التي تعدّل الكائن في مكانه لا ترجع القائمة نفسها؛ بل لا تعيد عنصرًا محددًا.

خطوات الحل السريع

  1. اقرأ الجزء 'str' داخل رسالة الخطأ؛ فهو يخبرك بنوع المتغير الحالي.
  2. ابحث عن المتغير قبل سطر الخطأ، وتأكد أين حصل على قيمته.
  3. استخدم type(variable) إذا لم تكن متأكدًا من نوعه.
  4. إذا كنت تريد تخزين عناصر متعددة، ابدأ بقائمة [].
  5. إذا كنت تريد دمج نصوص، استخدم + أو f-string أو join().
  6. لا تكتب items = items.append(value).
أخطاء شائعة عند استخدام append مع String وList في Python

مثال عملي كامل: برنامج بسيط لجمع أسماء

هذا البرنامج يطلب من المستخدم كتابة أسماء، ويضيف كل اسم إلى قائمة. عندما يضغط المستخدم 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() تجمع القائمة في نص واحد للعرض النهائي.

روابط داخلية مفيدة من بايثون العرب

الخلاصة

  • رسالة 'str' object has no attribute 'append' تعني أن المتغير نص وليس قائمة.
  • استخدم append() لإضافة عنصر إلى List فقط.
  • استخدم + أو f-string أو join() عندما تتعامل مع النصوص.
  • تذكر أن input() ترجع str دائمًا.
  • استخدم type() أو isinstance() لمعرفة نوع المتغير عند تشخيص الخطأ.
  • لا تخزن ناتج append() في المتغير نفسه لأنها لا ترجع قائمة جديدة.
{alertSuccess} قاعدة ذهبية: قبل كتابة variable.append(...)، تأكد أن variable قائمة فعلًا. وإذا كان نصًا، اسأل: هل أريد دمج نص؟ أم أريد جمع عدة عناصر داخل قائمة؟

مصادر خارجية رسمية للتوسع

أسئلة شائعة

ما معنى 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'> فهو قائمة.

إرسال تعليق

أحدث أقدم