يظهر خطأ NameError: name '...' is not defined في Python عندما يحاول البرنامج استخدام اسم لا يستطيع العثور عليه في النطاقات المتاحة وقت التنفيذ. قد يكون الاسم متغيرًا لم يُعرّف بعد، أو دالة لم يُنفّذ تعريفها، أو اسم مكتبة أو alias لم يتم استيراده، أو اسمًا كُتب بطريقة مختلفة.
NameError: name 'username' is not defined
الحل يبدأ من الاسم الظاهر داخل رسالة الخطأ: ابحث عنه في الكود، وتأكد أنه أصبح معرّفًا ومتاحًا في النطاق الحالي قبل السطر الذي يستخدمه، وأنك كتبته بنفس حالة الأحرف واستوردت المكتبة أو الاسم المطلوب عند الحاجة.
{alertInfo} الخلاصة السريعة:NameErrorيعني أن Python لم تجد الاسم المطلوب عند تنفيذ السطر. لا تغيّر الكود عشوائيًا؛ افحص الاسم نفسه، وترتيب التنفيذ، وScope، وimport.
هذا هو الدرس 9 من سلسلة مشكلة وحل في بايثون. وإذا كانت المشكلة في أساسيات إنشاء المتغيرات، راجع شرح المتغيرات في بايثون للمبتدئين.
{getToc} $title={محتوى المقال}
ما معنى خطأ NameError name is not defined؟
رسالة NameError: name is not defined تعني أن Python حاولت حل اسم محلي أو عام ولم تجده في النطاقات المتاحة. وجود الاسم في مكان آخر من الملف لا يكفي دائمًا؛ يجب أن يكون تعريفه قد أصبح متاحًا في المكان والوقت اللذين نُفذ فيهما السطر.
مثال بسيط:
print(username)
هذا الكود سيظهر خطأ لأن المتغير username غير معرف. بايثون لا تعرف ما هي قيمة username، لذلك تتوقف وتعرض رسالة خطأ.
لماذا يظهر NameError رغم أن الاسم موجود في الكود؟
هذه حالة شائعة في نتائج البحث: ترى الاسم في الملف، لكن Python ما زالت تقول إنه غير معرّف. السبب أن وجود الاسم نصيًا لا يعني أنه متاح عند تنفيذ السطر.
- قد يكون التعريف موجودًا بعد السطر الذي يستخدم الاسم.
- قد يكون الاسم داخل دالة أو Scope آخر وغير متاح من المكان الحالي.
- قد يكون هناك اختلاف بسيط في الكتابة أو حالة الأحرف، مثل
nameوName. - قد تكون نسيت
importأو استخدمت alias مثلpdأوnpدون تعريفه.
لذلك افحص دائمًا ترتيب التنفيذ والنطاق والكتابة والاستيراد، وليس مجرد وجود الكلمة في الملف.
الحل هو تعريف المتغير قبل استخدامه:
username = "Ahmed"
print(username)
الناتج:
Ahmed
السبب الأول: استخدام متغير قبل تعريفه
أشهر سبب لظهور خطأ NameError هو استخدام متغير قبل أن تعطيه قيمة.
مثال خاطئ:
print(age)
age = 20
هنا حاولنا طباعة age قبل تعريفه، لذلك لا تعرفه Python في هذا السطر.
الصحيح:
age = 20
print(age)
الناتج:
20
{alertSuccess} في بايثون ترتيب الكود مهم جدًا. يجب تعريف المتغير قبل استخدامه.
السبب الثاني: خطأ إملائي في اسم المتغير
أحيانًا يكون المتغير معرفًا بالفعل، لكنك تكتبه مرة باسم ومرة باسم آخر. في هذه الحالة ستتعامل بايثون معهما كمتغيرين مختلفين.
مثال خاطئ:
student_name = "Sara"
print(student_nam)
لاحظ أن المتغير الأصلي اسمه student_name، لكن في السطر الثاني كتبناه student_nam بدون حرف e في النهاية.
الصحيح:
student_name = "Sara"
print(student_name)
الناتج:
Sara
{alertWarning} بايثون حساسة لحالة الأحرف. المتغير name مختلف عن Name ومختلف عن NAME.
السبب الثالث: نسيان علامات الاقتباس حول النص
من الأخطاء الشائعة جدًا عند المبتدئين كتابة النص بدون علامات اقتباس. عندها تعتقد Python أن الكلمة اسم متغير وليست نصًا عاديًا.
مثال خاطئ:
print(Python)
هذا الكود لا يطبع كلمة Python، بل يبحث عن متغير اسمه Python. وبما أن هذا المتغير غير معرف، يظهر الخطأ.
الصحيح:
print("Python")
الناتج:
Python
{alertError} أي نص تريد طباعته كما هو يجب أن يكون بين علامات اقتباس، مثل "Python" أو 'Python'.
السبب الرابع: استدعاء دالة غير معرّفة أو قبل تنفيذ تعريفها
قد يظهر NameError إذا استدعيت اسم دالة غير موجود، أو إذا وصل التنفيذ إلى الاستدعاء قبل أن ينفذ سطر def الذي يربط الاسم بالدالة.
مثال خاطئ على مستوى الملف:
say_hello()
def say_hello():
print("Hello")
عند تنفيذ السطر الأول لم تكن Python قد نفذت تعريف say_hello بعد، لذلك يكون الاسم غير معروف في تلك اللحظة.
الصحيح أن يصل التنفيذ إلى تعريف الدالة أولًا:
def say_hello():
print("Hello")
say_hello()
الناتج:
Hello
السبب الخامس: استخدام متغير خارج نطاقه Scope
أحيانًا يكون المتغير موجودًا داخل دالة فقط، ثم تحاول استخدامه خارج الدالة. في هذه الحالة لا يكون المتغير معروفًا خارج نطاق الدالة.
مثال خاطئ:
def show_name():
name = "Omar"
print(name)
المتغير name تم إنشاؤه داخل الدالة، لذلك لا يمكن استخدامه مباشرة خارجها.
حل صحيح: اطبع المتغير داخل الدالة:
def show_name():
name = "Omar"
print(name)
show_name()
أو استخدم return لإرجاع القيمة:
def get_name():
name = "Omar"
return name
result = get_name()
print(result)
لشرح أعمق عن هذه الفكرة يمكنك قراءة: أساسيات بايثون 15: المتغيرات المحلية والعامة Scope في Python.
السبب السادس: نسيان import أو استخدام اسم module/alias غير معرّف
إذا استخدمت مكتبة مثل random أو math بدون استيرادها أولًا، فقد يظهر خطأ NameError.
مثال خاطئ:
print(random.randint(1, 10))
هنا استخدمنا random بدون كتابة import random.
الصحيح:
import random
print(random.randint(1, 10))
ينطبق الأمر نفسه على أسماء شائعة مثل os وpd وnp. مثلًا، استخدام pd.DataFrame يتطلب أن يكون الاسم pd قد عُرّف أولًا عادةً عبر import pandas as pd.
{alertInfo} إذا ظهرNameErrorمع اسم مكتبة أو alias، تحقق من سطرimportومن الاسم الذي استوردت به المكتبة، وليس من تثبيت المكتبة فقط.
جدول سريع لأسباب NameError وحلولها
| السبب | مثال على الخطأ | الحل |
|---|---|---|
| استخدام متغير قبل تعريفه | print(age) |
عرّف المتغير قبل استخدامه |
| خطأ إملائي في الاسم | student_nam |
اكتب اسم المتغير بنفس الشكل |
| نسيان علامات الاقتباس | print(Python) |
اكتب النص بين علامات اقتباس |
| استدعاء دالة غير معرفة | say_hello() |
عرّف الدالة قبل استدعائها |
| مشكلة في Scope | استخدام متغير محلي خارج الدالة | استخدمه داخل الدالة أو أعده باستخدام return |
| نسيان import | random.randint() |
اكتب import random أولًا |
كيف تصلح خطأ NameError خطوة بخطوة؟
عندما يظهر لك خطأ NameError، لا تغيّر الكود عشوائيًا. اتبع هذه الخطوات:
- اقرأ الاسم الموجود داخل رسالة الخطأ.
- ابحث عن هذا الاسم في الكود.
- تأكد أنه معرف قبل السطر الذي ظهر فيه الخطأ.
- تأكد أن الاسم مكتوب بنفس الحروف ونفس حالة الأحرف.
- إذا كان نصًا، تأكد أنه داخل علامات اقتباس.
- إذا كان دالة، تأكد أنها معرفة قبل استدعائها.
- إذا كان مكتبة، تأكد أنك كتبت
importبشكل صحيح.
{alertSuccess} أفضل طريقة لحل NameError هي قراءة الاسم الموجود في رسالة الخطأ، ثم التأكد أنه معرف ومكتوب بشكل صحيح قبل استخدامه.
مثال عملي كامل على تصحيح الخطأ
لنأخذ مثالًا فيه خطأ إملائي بسيط:
first_name = "Ali"
print(frist_name)
سيظهر خطأ لأننا كتبنا frist_name بدل first_name.
الحل:
first_name = "Ali"
print(first_name)
الناتج:
Ali
أخطاء قريبة من NameError
هناك أخطاء أخرى قد تبدو قريبة من NameError، لكنها تعني شيئًا مختلفًا:
| الخطأ | معناه باختصار |
|---|---|
UnboundLocalError |
غالبًا يظهر عند استخدام متغير محلي داخل دالة قبل إعطائه قيمة مناسبة. |
AttributeError |
يظهر عندما تستخدم دالة أو خاصية غير موجودة في نوع البيانات. |
ImportError |
يظهر عند وجود مشكلة في استيراد مكتبة أو عنصر من مكتبة. |
فهم نوع الخطأ يساعدك على اختيار الحل الصحيح بدل تجربة حلول عشوائية. إذا كانت الرسالة هي UnboundLocalError أو local variable referenced before assignment، فهذه حالة أكثر تحديدًا ولها شرح مستقل في حل خطأ UnboundLocalError في Python.
أخطاء شائعة يجب الانتباه لها
الخلط بين النص والمتغير
إذا أردت طباعة نص، استخدم علامات الاقتباس:
print("Hello")
أما إذا أردت طباعة قيمة متغير، فاكتب اسم المتغير بدون اقتباس:
message = "Hello"
print(message)
استخدام اسم مختلف بحرف كبير
هذا الكود خاطئ:
name = "Sara"
print(Name)
لأن name مختلف عن Name في بايثون.
نسيان تعريف الدالة
إذا استخدمت دالة باسم معين، تأكد أن تعريفها موجود:
def welcome():
print("Welcome")
welcome()
أسئلة شائعة
ما سبب خطأ NameError name is not defined في بايثون؟
السبب أنك استخدمت اسم متغير أو دالة أو مكتبة قبل تعريفه أو استيراده، أو كتبته بطريقة مختلفة عن الاسم الأصلي.
هل NameError يعني أن المتغير غير موجود؟
ليس بالضرورة أن الاسم غير موجود في الملف كله. المعنى الأدق أن Python لم تجد الاسم في النطاقات المتاحة عند تنفيذ السطر؛ قد يكون التعريف في Scope آخر، أو لم يُنفذ بعد، أو أن الاسم مكتوب بشكل مختلف.
لماذا يظهر NameError عند كتابة كلمة عادية؟
إذا كتبت كلمة بدون علامات اقتباس، ستتعامل معها Python كاسم متغير. لذلك النصوص يجب أن تكون بين علامات اقتباس.
هل اختلاف الحروف الكبيرة والصغيرة يسبب NameError؟
نعم. في بايثون name و Name و NAME أسماء مختلفة.
كيف أعرف السطر الذي سبب الخطأ؟
اقرأ رسالة الخطأ في الطرفية. غالبًا ستجد رقم السطر الذي ظهر فيه الخطأ، ثم اقرأ الاسم الموجود في الرسالة وراجعه في الكود.
مصادر رسمية للتوسع
الخلاصة
خطأ NameError: name is not defined في بايثون يظهر عندما تستخدم اسمًا غير معروف بالنسبة للغة، مثل متغير غير معرف، أو دالة غير موجودة، أو نص مكتوب بدون علامات اقتباس، أو مكتبة لم يتم استيرادها.
تذكر دائمًا:
- عرّف المتغير قبل استخدامه.
- اكتب اسم المتغير بنفس الشكل في كل مرة.
- ضع النصوص بين علامات اقتباس.
- عرّف الدوال قبل استدعائها.
- استورد المكتبات قبل استخدامها.
- انتبه لحالة الأحرف الكبيرة والصغيرة.
{alertSuccess} الخلاصة السريعة: عندما ترى NameError، ابحث عن الاسم الموجود في رسالة الخطأ، وتأكد أنه مكتوب ومعرّف بشكل صحيح قبل السطر الذي سبب المشكلة.
تمرين بسيط لك
حاول تصحيح الكود التالي:
course_name = "Python"
print(course)
سبب الخطأ أن المتغير الموجود هو course_name، لكننا حاولنا طباعة course.
الحل:
course_name = "Python"
print(course_name)