Замикання

Модуль 1: Python Core
Рівень 8 , Лекція 2
Відкрита

3.1 Знайомство з замиканнями

Замикання — це функція, яка захоплює змінні з своєї оточуючої області видимості, навіть після того, як ця область завершила своє виконання. Це означає, що замикання може «пам'ятати» значення змінних з своєї зовнішньої області видимості і продовжувати працювати з ними, навіть коли ця область більше не активна.

Щоб зрозуміти, як працюють замикання, розгляньмо наступний приклад:


def outer_function(x):
    def inner_function(y):
        return x + y

    return inner_function
    
closure = outer_function(10)
print(closure(5))  # Вивід: 15

Давайте розберемо, що тут написано:

Зовнішня функція (outer_function): Ця функція приймає аргумент x і визначає внутрішню функцію inner_function, яка приймає аргумент y і повертає суму x і y. Функція inner_function не викликається всередині outer_function, а тільки оголошується.

Внутрішня функція (inner_function): Ця функція повертається з outer_function і зберігає в собі посилання на значення x, яке було передано outer_function.

Замикання: Змінна closure стає замиканням, яке «пам'ятає» значення x (в даному випадку, 10) і може використовувати його при виклику.

Зазвичай ніхто з першого разу не може нормально працювати з замиканнями. Тож давайте спробуємо прокачати ваше розуміння замикань на прикладах.

3.2 Приклади використання замикань

Створення функції-генератора

Замикання можуть бути використані для створення функцій-генераторів, які генерують послідовності значень.


def make_counter():
    count = 0

    def counter():
        nonlocal count
        count += 1
        return count

    return counter
    
counter = make_counter()
print(counter())  # Вивід: 1
print(counter())  # Вивід: 2
print(counter())  # Вивід: 3

Пояснення:

Функція-генератор (make_counter): Ця функція створює змінну count і повертає внутрішню функцію counter, яка збільшує значення count і повертає його.

Замикання: Функція counter зберігає стан змінної count і може змінювати його при кожному виклику.

Створення функції з конфігурацією

Замикання можуть бути використані для створення функцій з попередньо визначеною конфігурацією.


def make_multiplier(factor):
    def multiplier(x):
        return x * factor

    return multiplier
    
double = make_multiplier(2)
triple = make_multiplier(3)
    
print(double(5))  # Вивід: 10
print(triple(5))  # Вивід: 15

Пояснення:

Функція-конфігуратор (make_multiplier): Ця функція приймає множитель factor і повертає внутрішню функцію multiplier, яка множить вхідне значення на factor.

Замикання: Функції double і triple є замиканнями, які зберігають свої власні значення factor і використовують їх для множення.

Фільтрація даних з параметрами

Замикання можуть бути корисні для створення фільтруючих функцій з параметрами.


def make_filter(threshold):
    def filter_func(value):
        return value > threshold
        
    return filter_func
    
filter_above_10 = make_filter(10)
data = [5, 10, 15, 20]
filtered_data = list(filter(filter_above_10, data))
print(filtered_data)  # Вивід: [15, 20]

Пояснення:

Функція-фільтр (make_filter): Ця функція приймає порогове значення threshold і повертає внутрішню функцію filter_func, яка перевіряє, чи перевищує значення поріг.

Замикання: Функція filter_func зберігає значення threshold і використовує його для фільтрації даних.

3.3 Плюси і мінуси замикань

Переваги використання замикань

Інкапсуляція стану: Замикання дозволяють інкапсулювати стан в функції, уникаючи глобальних змінних і покращуючи читабельність та підтримку коду.

Гнучкість: Замикання можуть бути використані для створення функцій з певною конфігурацією або поведінкою, що робить код більш гнучким і адаптованим.

Функціональне програмування: Замикання є важливою концепцією в функціональному програмуванні, дозволяючи створювати функції вищого порядку та інші функціональні конструкції.

Обмеження та потенційні проблеми

Попри багато переваг, замикання мають і свої обмеження:

Використання пам'яті: Замикання можуть утримувати посилання на об'єкти, які більше не використовуються, що може призвести до витоків пам'яті.

Складність відладки: Замикання можуть ускладнити відладку коду, оскільки стани змінних можуть бути неочевидними.

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ