0Pricing
Python Academy · درس

nonlocal والحالة القابلة للتغيير

عدّل النطاق المحيط

nonlocal والحالة القابلة للتغيير درس مجاني في Python Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Python Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Python Academy 4 دروس في المجموع.

قراءة المتغيرات المحيطة وكتابتها

يمكن للدالة الداخلية قراءة متغير محيط بحرية، لكنها إذا حاولت إسناد قيمة إلى ذلك الاسم، فستتعامل Python معه باعتباره متغيرًا محليًا جديدًا. وغالبًا ما يفاجئ هذا المبتدئين.

def outer():
    count = 0
    def inner():
        return count
    return inner()
print(outer())

مأزق الإسناد

يؤدي الإسناد إلى اسم محيط من دون التصريح بالنية إلى جعله محليًا، ولذلك لا يُحدَّث المتغير الخارجي مطلقًا. وهنا تضيع التغييرات.

def outer():
    count = 0
    def bump():
        count = count + 1
    try:
        bump()
    except UnboundLocalError as e:
        print('Error:', e)
outer()

الكلمة المفتاحية nonlocal

تصرّح nonlocal بأن الاسم يشير إلى متغير في أقرب نطاق دالة محيطة، ولذلك تُحدّث عمليات الإسناد ذلك المتغير الخارجي بدلًا من إنشاء متغير محلي.

def outer():
    count = 0
    def bump():
        nonlocal count
        count += 1
    bump()
    bump()
    return count
print(outer())

إغلاق العداد

باستخدام nonlocal، يمكنكم إنشاء عداد يحتفظ بحالته. إذ تعدّل كل استدعاءات المتغير الملتقط وتحتفظ بتقدمه.

def make_counter():
    count = 0
    def increment():
        nonlocal count
        count += 1
        return count
    return increment
c = make_counter()
print(c())
print(c())
print(c())

عدادات مستقلة

يحتفظ كل عداد بحالته الخاصة، لأن كل إغلاق يلتقط متغيرًا منفصلًا.

def make_counter():
    count = 0
    def inc():
        nonlocal count
        count += 1
        return count
    return inc
a = make_counter()
b = make_counter()
print(a(), a(), b())

nonlocal مقابل global

يستهدف nonlocal نطاق دالة محيطة، بينما يستهدف global مستوى الوحدة. استخدموا nonlocal مع الإغلاقات وglobal للحالة على مستوى الوحدة.

total = 0
def add_global(n):
    global total
    total += n
add_global(5)
add_global(3)
print(total)

حالة قابلة للتغيير دون nonlocal

إذا كانت القيمة المحيطة كائنًا قابلًا للتغيير، مثل قائمة أو قاموس، فيمكنكم تعديلها موضعيًا من دون nonlocal، لأنكم لا تعيدون إسناد الاسم.

def make_logger():
    history = []
    def log(msg):
        history.append(msg)
        return history
    return log
log = make_logger()
log('start')
print(log('stop'))

المجمِّع التراكمي

يتيح الجمع بين nonlocal والإغلاق إنشاء مجمِّع تراكمي يضيف كل قيمة إلى مجموع محفوظ.

def make_accumulator():
    total = 0
    def add(n):
        nonlocal total
        total += n
        return total
    return add
acc = make_accumulator()
print(acc(10))
print(acc(5))
print(acc(100))

تبديل بسيط

يجعل nonlocal تبديل الحالة المنطقية بين الاستدعاءات أمرًا سهلًا.

def make_toggle():
    on = False
    def toggle():
        nonlocal on
        on = not on
        return on
    return toggle
t = make_toggle()
print(t(), t(), t())

إعادة ضبط الحالة

يمكنكم إتاحة عدة دوال داخلية تشترك في الحالة المحيطة نفسها، مثل دالة للإضافة وأخرى لإعادة الضبط.

def make_bank():
    balance = 0
    def deposit(n):
        nonlocal balance
        balance += n
        return balance
    def reset():
        nonlocal balance
        balance = 0
        return balance
    return deposit, reset
deposit, reset = make_bank()
print(deposit(50))
print(reset())

يحتاج nonlocal إلى متغير موجود

يتطلب nonlocal أن يكون الاسم موجودًا مسبقًا في نطاق محيط؛ وإلا فسترفع Python استثناء SyntaxError وقت التعريف. ولا يمكنه إنشاء متغير خارجي جديد.

def outer():
    value = 'set'
    def inner():
        nonlocal value
        value = 'changed'
    inner()
    return value
print(outer())

تحقق سريع

تريدون داخل دالة متداخلة إعادة إسناد قيمة إلى متغير من الدالة المحيطة. ما الكلمة المفتاحية التي تستخدمونها؟

مراجعة: nonlocal والحالة القابلة للتغيير

الملخص:

  • ينشئ الإسناد إلى اسم محيط متغيرًا محليًا جديدًا عادةً؛ ويمنع nonlocal ذلك.
  • يستهدف nonlocal نطاق الدالة المحيطة، بينما يستهدف global الوحدة.
  • لا يتطلب تعديل كائن قابل للتغيير موضعيًا أي تصريح.
  • تنشئ الإغلاقات مع nonlocal عدادات ومجمّعات تراكمية ومفاتيح تبديل تتذكر الحالة.
def make_counter():
    n = 0
    def inc():
        nonlocal n
        n += 1
        return n
    return inc
c = make_counter()
print(c(), c())

الأسئلة الشائعة

هل درس «nonlocal والحالة القابلة للتغيير» مجاني؟

نعم — نص درس «nonlocal والحالة القابلة للتغيير» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Python Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Python Academy 4 دروس في المجموع.

ماذا ستتعلم في «nonlocal والحالة القابلة للتغيير»؟

عدّل النطاق المحيط تتمرن على Python Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Python Academy؟

لا تُشترط خبرة سابقة. Python Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.

كم من الوقت يستغرق درس «nonlocal والحالة القابلة للتغيير»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Python Academy هذا؟

نعم. كل درس في Python Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. الدوال من الدرجة الأولى
  2. الإغلاقات والمتغيرات الحرة
  3. nonlocal والحالة القابلة للتغيير
  4. الدوال الجزئية
← العودة إلى Python Academy