English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
في هذا المقال، ستتعرف على ما هو ربط بايثون وكيفية تعريف الربط وأسباب استخدامه.
قبل فهم ما هو الربط يجب علينا أولاً فهم ما هو الدوال الداخلية والمتغيرات غير المحلية.
الوظيفة المُحددة داخل وظيفة أخرى تُسمى وظيفة محكومة. يمكن للوظيفة المحكومة الوصول إلى المتغيرات في النطاق المحكم.
بافتراض الافتراض في بايثون، هذه المتغيرات غير المحلية هي قابلة للقراءة فقط، وعلينا أن نُعلنها كغير محلية بوضوح (باستخدامكلمة المفتاح nonlocal) لتحديثها.
هذا مثال على وظيفة محكومة داخلية تُستخدم لتحديد المتغيرات غير المحلية.
def print_msg(msg): # هذا هو الوظيفة المحكومة الخارجية. def printer(): # هذا هو اللفظ المحكوم. print(msg) printer() # نحن نُنفيذ هذه الوظيفة. # الناتج: Hello print_msg("Hello")
نستطيع أن نرى أن وظيفة printer() المحكومة يمكنها الوصول إلى المتغيرات غير المحلية في الوظيفة المحكومة.msg.
ماذا سيحدث إذا عادت وظيفة print_msg() في السطر الأخير إلى وظيفة printer() بدلاً من استدعائها؟ هذا يعني أن التعريف التالي للوظيفة هو كالتالي.
def print_msg(msg): # هذا هو الوظيفة المحكومة الخارجية. def printer(): # هذا هو اللفظ المحكوم. print(msg) return printer # هذا تغير. # الآن، دعونا نحاول استدعاء هذه الوظيفة. # الناتج: Hello another = print_msg("Hello") another()
هذا غير اعتيادي.
وظيفة print_msg() تُستدعى باستخدام 字符ية، "Hello"، وتُربط الوظيفة التي تُستدعى باللفظ print_msg("Hello").أخرىاسم. عند استدعاء another()، على الرغم من أننا قد أنهينا تنفيذ وظيفة print_msg()، لا زلنا نتذكر الرسالة.
هذه التقنية التي يتم إضافة بعض البيانات ("Hello") إلى الكود.في بايثونيسمىاللفظ المحكوم.
حتى إذا كانت المتغيرات قد تجاوزت نطاقها أو تم حذف الوظيفة نفسها من النطاق الحالي، فإنها تذكر هذه القيمة في النطاق المحكم.
حاول تشغيل الأوامر التالية في محطة بايثون لرؤية الناتج.
>>> del print_msg >>> another() Hello >>> print_msg("Hello") Traceback (أحدث استدعاء): ... NameError: اسم 'print_msg' غير معرف.
من خلال النظر في المثال السابق، يمكننا رؤية أننا نملك لفظ محكوم في بايثون عندما يشير اللفظ المحكوم إلى قيمة في نطاقه المحكم.
النقاط التالية تلخص الشروط التي يجب أن تُ satisfy لتكوين اللفظ المحكوم في بايثون.
يجب أن يكون لدينا وظيفة محكومة داخل وظيفة (وظيفة داخل وظيفة).
الوظيفة المحكومة يجب أن تشير إلى القيم المحددة في الوظيفة المحكومة.
الوظيفة المحكومة يجب أن تعود الوظيفة المحكومة.
那么,闭包有什么用呢?
闭包可以避免使用全局值,并提供某种形式的数据隐藏。它还可以为该问题提供面向对象的解决方案。
当在一个类中实现的方法很少(大多数情况下是一个方法)时,闭包可以提供另一种更优雅的解决方案。但是,当属性和方法的数量变大时,最好实现一个类。
这是一个简单的示例,其中闭包可能比定义类和创建对象更可取。
def make_multiplier_of(n): def multiplier(x): return x * n return multiplier # 3的乘数 times3 = make_multiplier_of(3) # 5的乘数 times5 = make_multiplier_of(5) # 输出: 27 print(times3(9)) # 输出: 15 print(times5(3)) # 输出: 30 print(times5(times3(2)))
Python中的装饰器也大量使用了闭包。
最后,最好指出可以找到封闭在封闭函数中的值。
所有函数对象都有一个__closure__属性,如果它是一个闭包函数,则该属性返回单元格对象的元组。参考上面的示例,我们知道times3和times5是闭包函数。
>>> make_multiplier_of.__closure__ >>> times3.__closure__ (<cell at 0x0000000002D155B8: int object at 0x000000001E39B6E0>,)
单元格对象具有存储关闭值的属性cell_contents。
>>> times3.__closure__[0].cell_contents 3 >>> times5.__closure__[0].cell_contents 5