🔍 فهم نطاقات المتغيرات (Scopes) في بايثون: دليلك الشامل للمبتدئين
اليوم سنتعرف على مفهوم بالغ الأهمية في البرمجة بشكل عام وفي بايثون بشكل خاص: نطاقات المتغيرات أو Scopes. إذا كنت قد واجهت رسالة خطأ تقول NameError: name 'x' is not defined من قبل، فهذا الدرس سيساعدك على فهم سبب هذا الخطأ وكيف تتجنبه.
🎯 ما هو النطاق (Scope)؟
النطاق هو المنطقة أو السياق في برنامجك حيث يتم تعريف المتغير ويمكن الوصول إليه. تخيل أن النطاق يشبه الغرف في منزلك:
- بعض الأشياء موجودة في غرفة النوم (محلية) ولا يمكن رؤيتها من الغرفة الأخرى
- بعض الأشياء موجودة في الصالة (عامة) ويمكن للجميع رؤيتها
في بايثون، النطاق يحدد أين يمكنك استخدام متغير معين في الكود.
# هذا متغير عام (في النطاق العام)
global_var = "أنا متغير عام"
def my_function():
# هذا متغير محلي (داخل النطاق المحلي للدالة)
local_var = "أنا متغير محلي"
print(global_var) # ✓ يمكن الوصول للمتغير العام
print(local_var) # ✓ يمكن الوصول للمتغير المحلي
my_function()
print(global_var) # ✓ يمكن الوصول للمتغير العام
# print(local_var) # ❌ خطأ! لا يمكن الوصول للمتغير المحلي خارج الدالة
📍 أنواع النطاقات في بايثون
1. النطاق المحلي (Local Scope)
هو النطاق داخل الدالة. المتغيرات المعرفة داخل دالة تكون محلية وتوجد فقط داخل تلك الدالة.
def calculate_sum(a, b):
result = a + b # 'result' متغير محلي
return result
# print(result) # ❌ خطأ! 'result' غير معروف خارج الدالة
2. النطاق العام (Global Scope)
هو النطاق خارج أي دالة. المتغيرات المعرفة هنا تكون عامة ويمكن الوصول لها من أي مكان في البرنامج.
website_name = "Codex Academy" # متغير عام
def welcome_message():
message = "Welcome to " + website_name # ✓ يمكن الوصول للمتغير العام
return message
print(welcome_message())
3. النطاق غير المحلي (Nonlocal Scope)
يظهر عندما يكون لدينا دوال داخل دوال (دوال متداخلة).
def outer_function():
outer_var = "أنا في النطاق الخارجي"
def inner_function():
nonlocal outer_var # نستخدم nonlocal للوصول لمتغير الدالة الخارجية
outer_var = "تم التعديل من الدالة الداخلية"
inner_function()
print(outer_var) # سيطبع: "تم التعديل من الدالة الداخلية"
outer_function()
🧠 قاعدة LEGB: ترتيب البحث عن المتغيرات
عندما تطلب بايثون قيمة متغير، تبحث فيه بالترتيب التالي:
- Local - النطاق المحلي (داخل الدالة الحالية)
- Enclosing - النطاق المحيط (في الدوال الخارجية)
- Global - النطاق العام
- Built-in - النطاق المدمج (الدوال المضمنة في بايثون)
x = "عام" # النطاق العام
def test_scope():
x = "محلي" # النطاق المحلي
print(x) # سيطبع: "محلي" (يأخذ القيمة من النطاق المحلي)
test_scope()
print(x) # سيطبع: "عام" (يأخذ القيمة من النطاق العام)
⚠️ الأخطاء الشائعة وكيفية تجنبها
الخطأ: محاولة تعديل متغير عام بدون كلمة global
counter = 0
def increment():
# counter += 1 # ❌ خطأ! لا يمكن تعديل المتغير العام مباشرة
global counter # ✓ الحل الصحيح
counter += 1
increment()
print(counter) # سيطبع: 1
الخطأ: الخلط بين المتغيرات المحلية والعامة
name = "Ahmed"
def change_name():
name = "Mohamed" # هذا ينشئ متغير محلي جديد، لا يعدل المتغير العام
print("داخل الدالة:", name)
change_name() # يطبع: داخل الدالة: Mohamed
print("خارج الدالة:", name) # يطبع: خارج الدالة: Ahmed
💡 نصائح عملية لاستخدام النطاقات
- استخدم متغيرات محلية قدر الإمكان لتجنب التضارب
- قلل استخدام المتغيرات العامة إلا عند الضرورة
- استخدم أسماء متغيرات واضحة لتجنب الخلط
- افهم دائماً أين عرفت المتغير قبل استخدامه
# مثال جيد لاستخدام النطاقات
def calculate_area(radius):
pi = 3.14159 # متغير محلي مناسب
area = pi * radius ** 2
return area
# استخدام الدالة بشكل صحيح
circle_area = calculate_area(5)
print("مساحة الدائرة:", circle_area)
🎓 خلاصة الدرس
- النطاق المحلي: داخل الدالة، متاح فقط داخلها
- النطاق العام: خارج الدوال، متاح في كل مكان
- النطاق غير المحلي: للدوال المتداخلة، نستخدم
nonlocal - قاعدة LEGB: ترتيب البحث عن المتغيرات
- تجنب الأخطاء: استخدام
globalعند تعديل المتغيرات العامة
🎓 اختبر نفسك
السؤال 1 من 30% أكملت
ما هو النطاق الذي يتم تعريف المتغيرات فيه بحيث تكون متاحة فقط داخل الدالة التي عُرِّفت فيها؟
آخر تحديث: ٢٢ مارس ٢٠٢٦
التعليقات
شاركنا رأيك أو أسئلتك حول هذا المقال
جاري تحميل التعليقات...