У Python закриття - це екземпляр функції, яка має незмінні зв’язані з нею змінні.
Насправді, модель даних пояснює це в описі __closure__
атрибута функцій :
Жодна або набір комірок, які містять прив’язки для вільних змінних функції. Лише для читання
Щоб продемонструвати це:
def enclosure(foo):
def closure(bar):
print(foo, bar)
return closure
closure_instance = enclosure('foo')
Очевидно, ми знаємо, що тепер у нас є функція, на яку вказує ім’я змінної closure_instance
. Нібито, якщо ми називаємо це за допомогою об'єкта, bar
він повинен надрукувати рядок 'foo'
і будь-яке представлення рядка bar
.
Насправді, рядок «Foo» буде пов'язаний з екземпляром функції, і ми можемо відразу прочитати його тут, шляхом доступу до cell_contents
атрибуту (тільки і) першого осередку в кортежі __closure__
атрибута:
>>> closure_instance.__closure__[0].cell_contents
'foo'
Окрім того, об’єкти комірки описані в документації C API:
Об'єкти "комірка" використовуються для реалізації змінних, на які посилаються кілька областей
І ми можемо продемонструвати використання нашого закриття, зазначивши, що 'foo'
воно застрягло у функції і не змінюється:
>>> closure_instance('bar')
foo bar
>>> closure_instance('baz')
foo baz
>>> closure_instance('quux')
foo quux
І ніщо не може це змінити:
>>> closure_instance.__closure__ = None
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: readonly attribute
Часткові функції
Наведений приклад використовує закриття як часткову функцію, але якщо це єдина наша мета, та ж мета може бути досягнута за допомогою functools.partial
>>> from __future__ import print_function
>>> partial_function = functools.partial(print, 'foo')
>>> partial_function('bar')
foo bar
>>> partial_function('baz')
foo baz
>>> partial_function('quux')
foo quux
Є також більш складні закриття, які не відповідають прикладу часткових функцій, і я продемонструю їх далі, як дозволить час.
nonlocal
доданий у python 3, python 2.x не мав повноцінного закриття, читання-запис (тобто ви могли читати закриті над змінними, але не змінювати їх значення)