Давайте поговорим о закрытиях в Python | Python Theme месяц

задняя часть Python
Давайте поговорим о закрытиях в Python | Python Theme месяц

Эта статья участвует в "Месяце тем Python", подробнее см.Ссылка на мероприятие

Вы изучите замыкания Python, как определить замыкание в Python и как использовать замыкания. Всем известно, что в функциональном программировании легко реализовать каррирование, если у вас есть замыкания. Есть много замыканий, например, локальные переменные в функции могут быть сохранены после выполнения функции, и возвращается внутренняя ссылка на функцию.

Нелокальные переменные во вложенных функциях

Прежде чем обсуждать, что такое замыкания, необходимо понять, что такое вложенные функции и нелокальные переменные. Определение функций внутри функции называется вложенной функцией. Вложенные функции могут обращаться к переменным внутри функции, в которой они расположены, следующим образом

def func():
    msg = "hello"
    def inner():
        print(msg)

    inner()

func()

.

В Python эти нелокальные переменные (msg = "hello") По умолчанию доступно только для чтения, если вы хотите, чтобы вложенная функция inner()изменить внешнийmsg, вам нужно отобразить ключевое словоnonlocalЯвно объявите ее как нелокальную переменную, прежде чем вы сможете ее изменить.

def func():
    msg = "hello"
    def inner():
        msg ="world"
    inner()
    print(msg) # hello
func()

Если вы хотите изменить переменную msg, область действия которой находится в области видимости func, вам нужно добавить nonlocal перед переменной во вложенной функции, чтобы можно было изменить и переменную во вложенной функции-обертке.

def func():
    msg = "hello"
    def inner():
        nonlocal msg
        msg ="world"
    inner()
    print(msg)# print world
func()

определить закрытие

В приведенном выше примере, если функцияprint_msg()Последняя строка возвращаетсяprinterвместо вызова этой функции, что происходит? Это означает, что функция определяется следующим образом.

def print_msg(msg):

    def printer():
        print(msg)

    return printer  # returns the nested function


# Output: Hello
another = print_msg("Hello")
another()

перечислитьprint_msg() Параметр, передаваемый функции, представляет собой строку «Hello», а возвращаемая функция присваивается переменной other. при звонкеanother(), хотя и законченprint_msg()Функция выполняется, но значение переменной msg сохраняется. Этот метод вызова переменной с некоторыми данными («Hello» в данном случае) из внутренней функции, и когда завершается выполнение функции-обертки, переменная остается, технически вызываемая в Python.Закрытие.

def print_msg(msg):

    def printer():
        print(msg)

    return printer  # returns the nested function


# Output: Hello
another = print_msg("Hello")
another()

del print_msg
another() # Hello
# print_msg("Hello")

Когда у нас закрытие?

Как вы можете видеть из приведенного выше примера, у нас есть замыкание в Python, когда вложенная функция ссылается на значение в своей области видимости.

Условия, которые должны быть соблюдены для создания замыкания в Python, приведены в следующих пунктах.

  • Есть вложенные функции
  • Часто вложенные функции ссылаются на переменные, определенные во внешних функциях.
  • Вложенная функция должна быть внешней функцией, возвращаемой

Когда использовать окклюдер?

Итак, какая польза от замыканий? Далее, давайте взглянем на некоторые функции замыканий. Замыкания позволяют избежать использования глобальных переменных и обеспечивают некую форму конфиденциальности переменных, что является объектно-ориентированным решением. Когда классу необходимо реализовать очень мало методов (в большинстве случаев один метод), замыкания могут предоставить другой способ реализации инкапсуляции, более элегантное решение. Но если количество свойств и методов растет, лучше реализовать класс.

def make_multiplier_of(n):
    def multiplier(x):
        return x * n
    return multiplier


# Multiplier of 3
times3 = make_multiplier_of(3)

# Multiplier of 5
times5 = make_multiplier_of(5)

# Output: 27
print(times3(9))

# Output: 15
print(times5(3))

# Output: 30
print(times5(times3(2)))

Реализация декоратора Python также активно использует замыкания. Наконец, следует отметить, что вложенное значение объемлющей функции может быть обнаружено. В начале упоминалось, что замыкания также используются в каррировании для реализации функций, которые разбивают многопараметрическую функцию на несколько последовательностей однопараметрических функций.

def make_multiplier_of(n):
    def multiplier(x):
        return x * n
    return multiplier


print(make_multiplier_of.__closure__) #None

Все функциональные объекты имеют__closure__свойство, если функция замыкания, возвращает кортеж объектов ячеек. Ссылаясь на приведенный выше пример, мы знаем, чтоtimes3иtimes5является закрытой функцией.

def make_multiplier_of(n):
    def multiplier(x):
        return x * n
    return multiplier

time3 = make_multiplier_of(3)
time5 = make_multiplier_of(5)
print(time3(2))

print(make_multiplier_of.__closure__) #None
print(time3.__closure__[0].cell_contents) #3
print(time5.__closure__[0].cell_contents) #5

посредством следующихtime3.__closure__[0].cell_contentsПросмотр значений параметров, переданных при вызове.