0Pricing
Python Academy · درس

الإغلاقات والمتغيرات الحرة

التقط الحالة داخل الدوال الداخلية

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

الدوال المتداخلة

تتيح Python تعريف دالة داخل دالة أخرى. وتُنشأ الدالة الداخلية من جديد في كل مرة تُشغَّل فيها الدالة الخارجية.

def outer():
    def inner():
        return 'from inner'
    return inner()
print(outer())

ترى الداخلية متغيرات الخارجية

يمكن للدالة الداخلية قراءة المتغيرات المعرّفة في الدالة المحيطة. وتُسمى هذه المتغيرات متغيرات حرة لأنها ليست محلية للدالة الداخلية.

def outer():
    message = 'hello'
    def inner():
        return message
    return inner()
print(outer())

ما الإغلاق؟

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

def make_greeter(name):
    def greet():
        return 'Hi ' + name
    return greet
g = make_greeter('Ada')
print(g())

تبقى الحالة الملتقطة

لقد أُرجعت الدالة الخارجية بالفعل، ومع ذلك يظل الإغلاق محتفظًا بـ name. وتبقى القيمة موجودة داخل الدالة المُرجعة.

def make_greeter(name):
    def greet():
        return 'Hi ' + name
    return greet
a = make_greeter('Ada')
b = make_greeter('Bob')
print(a())
print(b())

مصنع لدوال الضرب

تتألق الإغلاقات عند استخدامها كمصانع تنتج دوالًا مخصصة. هنا تضرب كل دالة مُرجعة في عامل ملتقط.

def multiplier(factor):
    def multiply(n):
        return n * factor
    return multiply
double = multiplier(2)
triple = multiplier(3)
print(double(10))
print(triple(10))

كل إغلاق مستقل

ينشئ كل استدعاء للمصنع إغلاقًا منفصلًا بقيمته الملتقطة الخاصة. ولا تتداخل الإغلاقات مع بعضها.

def adder(amount):
    def add(n):
        return n + amount
    return add
add5 = adder(5)
add100 = adder(100)
print(add5(1), add100(1))

فحص القيم الملتقطة

تُدرج الأسماء الملتقطة في __code__.co_freevars، بينما توجد قيمها في خلايا __closure__.

def make(x):
    def f():
        return x
    return f
fn = make(42)
print(fn.__code__.co_freevars)
print(fn.__closure__[0].cell_contents)

تلتقط الإغلاقات المتغيرات لا القيم

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

def build():
    x = 1
    def show():
        return x
    x = 99
    return show
print(build()())

مأزق الربط المتأخر في الحلقات

هذه مشكلة شائعة: تشترك الإغلاقات المنشأة داخل حلقة في متغير الحلقة نفسه، ولذلك تلتقط قيمته الأخيرة.

funcs = []
for i in range(3):
    funcs.append(lambda: i)
print([f() for f in funcs])

إصلاح الربط المتأخر

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

funcs = []
for i in range(3):
    funcs.append(lambda i=i: i)
print([f() for f in funcs])

الإغلاقات ككائنات خفيفة

يجمع الإغلاق بين البيانات والسلوك، مثل كائن صغير — وغالبًا ما يكون أنظف من فئة كاملة في الحالات البسيطة.

def counter_start(start):
    def value():
        return start
    return value
c = counter_start(10)
print(c())

تحقق سريع

ما الإغلاق في Python؟

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

الأفكار الأساسية:

  • يمكن للدوال الداخلية قراءة متغيرات النطاق المحيط (المتغيرات الحرة).
  • الإغلاق هو دالة داخلية مُرجعة تتذكر تلك المتغيرات.
  • ينشئ كل استدعاء للمصنع إغلاقًا مستقلًا.
  • تلتقط الإغلاقات المتغيرات لا القيم، ما يسبب مأزق الربط المتأخر في الحلقات — ويمكن إصلاحه باستخدام وسيط افتراضي.
def power_of(exp):
    return lambda base: base ** exp
square = power_of(2)
print(square(9))

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

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

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

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

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

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

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

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

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

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

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

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

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