Періодично в різних джерелах спливають ось такі ось шматки коду:
Що це? Зазвичай таке визначення функції inner_func називають замиканням (closure) - ми визначили функцію всередині іншої (зовнішньої) функції замкнувши її щодо зовнішньої функції.
І навіщо вони потрібні? Для чого згодяться замикання?
- Усунення жорстко кодованих констант
- Усунення в коді глобальних змінних
- Для реалізації ГО
Все виглядає круто, але знову ж таки не зрозуміло: "шо це такоє" оО. Виглядає як визначення декоратора, повертає функцію. Ні-і-і зрозуміло. Як мені здається, плутанина створюється через загальноприйнятого сприйняття замикань у відриві від їх витоків. Якщо звернутися до чудової книзі "Структура та інтерпретація комп'ютерних програм", то знайдемо там дуже просте визначення замикання:
У загальному випадку, операція комбінування об'єктів даних має властивість замикання в тому випадку, якщо результати з'єднання об'єктів за допомогою цієї операції самі можуть з'єднуватися цієї ж операцією
Тепер уже код вище не повинен викликати жодних нарікань. Він чітко підходить під визначення. А заодно з цього визначення стає ясно, що поняття "замикання" значно ширше. Наприклад, список. Елементи списку також можуть або є списками - це замикання в сенсі SICP. Тільки в пітонячей середовищі не прийнято на це увагу звертати, та й особливого сенсу немає. Методи об'єктів також є замиканнями. Вони замкнуті щодо об'єкта self, який завжди передається першим аргументом.
застосування замикань
Із застосуванням замикання в Python ви зустрічаєтеся кожен день. Це і методи, і декоратори функцій і класів, списки, кортежі і т.д. Розглянемо приклад замикання в вигляді декоратора, який перевіряє яким HTTP методом було скоєно звернення до view в Django фреймворку. Працює він так: перевіряємо метод, якщо метод дозволений, то відпрацьовуємо view, якщо не вирішено викидаємо виняток:
І на останок
Є один нюанс. У Пітоні замкнуті змінні доступні тільки для читання. Щоб обійти таке обмеження, потрібно замикати змінні контейнерного типу: списки, кортежі і т.д. Самі замкнуті змінні можна буде перезаписувати, а от вміст контейнера - будь ласка.
Сильно гріти голову про замиканнях не слід. Розробники мови про все вже подумали. Зокрема, зробили їх застосування максимально прозорим для програмістів. Але знання сакральних особливостей допоможе вам відчувати себе краще і глибше розуміти поведінку вашого python-коду.
Слідкуйте за нашими публікаціями і ви дізнаєтеся ще більше про сакральні особливості Python, які зроблять з вас видатного програміста на мові Python! ^ __