Уведомления

Группа в Telegram: @pythonsu

#1 Фев. 17, 2022 21:23:58

hendeman
Зарегистрирован: 2021-11-01
Сообщения: 3
Репутация: +  0  -
Профиль   Отправить e-mail  

Замыкания, вложенные функции

При изучении темы замыкания, возникло недопонимание для чего это вообще нужно
Пример кода:

 def number(num):
    def new_number(a):
        return num + a
    return new_number
 print(number(10)(3))
А вот моя реализация, которая укладывается в голове
 def number_1(num, a):
    def new_number(b):
        return num + b
    return new_number(a)
 print(number_1(10, 3))
Результат получается одинаковый. Поясните, пожалуйста, в чем существенная разница и преимущества первого способа

Офлайн

#2 Фев. 18, 2022 04:06:57

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9873
Репутация: +  853  -
Профиль   Отправить e-mail  

Замыкания, вложенные функции

hendeman
При изучении темы замыкания, возникло недопонимание для чего это вообще нужно
Ты создаёшь замыкание, а потом пользуешься им многократно.
  
>>> def search_string(pattern):
...     def f(string):
...         return pattern in string
...     return f
... 
>>> searcher_john = search_string('John')
>>> searcher_mary = search_string('Mary')
>>> 
>>> for s in ('Bob went to the shop',
...           'I saw John near the car',
...           'Her name was Mary'):
...     if searcher_john(s):
...         print('I see John in', repr(s))
...     if searcher_mary(s):
...         print('I see Mary in', repr(s))
... 
I see John in 'I saw John near the car'
I see Mary in 'Her name was Mary'
>>> 
>>> searchers = tuple((i, search_string(i)) for i in ('near', 'car', 'name'))
>>> 
>>> for s in ('Bob went to the shop',
...           'I saw John near the car',
...           'Her name was Mary'):
...     for searcher_s, searcher_f in searchers:
...         if searcher_f(s):
...             print('I see {} in'.format(searcher_s), repr(s))
... 
I see near in 'I saw John near the car'
I see car in 'I saw John near the car'
I see name in 'Her name was Mary'
>>>
Тут один раз написана функция, возвращающая замыкание. Потом пять замыканий делается с помощью этой одной функции. А потом каждое из пяти замыканий используется многократно. Каждое из пяти замыканий помнит свои индивидуальные настройки.



Отредактировано py.user.next (Фев. 18, 2022 04:14:08)

Офлайн

#3 Фев. 18, 2022 11:26:50

xam1816
Зарегистрирован: 2020-05-11
Сообщения: 1352
Репутация: +  118  -
Профиль   Отправить e-mail  

Замыкания, вложенные функции

hendeman
возникло недопонимание для чего это вообще нужно
еще замыкание можно использовать чтобы хранить свое последнее состояние
как пример это числа фибоначчи, можно каждый раз вычислять от 0 до нужного числа,что неэффективно, а можно просто запомнить последнее высчитанное число с помощью замыкания.Числа Фибоначчи полученные рекурсией, уступают замыканию на больших значениях
 def fib():
    x0 = 0
    x1 = 1
    print('изначальное состояние двух переменных', x0, x1,'\n')
    def get_next_num():
        nonlocal x0, x1
        print(f'храню предыдущее состояние x0,x1 = {x0}, {x1}')
        x0, x1 = x1, x1 + x0
        print('новый расчет выдал результат = ', x1)
        print("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^")
        return x1
    return get_next_num
f = fib()
f()
f()
f()
f()
print('в памяти храним только предыдущее состояние, так как только оно нам нужно для расчетов')
print('а не высчитывая всю цепочку начиная от 0\n')
f()
изначальное состояние двух переменных 0 1 

храню предыдущее состояние x0,x1 = 0, 1
новый расчет выдал результат = 1
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
храню предыдущее состояние x0,x1 = 1, 1
новый расчет выдал результат = 2
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
храню предыдущее состояние x0,x1 = 1, 2
новый расчет выдал результат = 3
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
храню предыдущее состояние x0,x1 = 2, 3
новый расчет выдал результат = 5
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
в памяти храним только предыдущее состояние, так как только оно нам нужно для расчетов
а не высчитывая всю цепочку начиная от 0

храню предыдущее состояние x0,x1 = 3, 5
новый расчет выдал результат = 8
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Process finished with exit code 0

По принципу замыкания в питоне сделаны декораторы

Отредактировано xam1816 (Фев. 18, 2022 16:37:43)

Офлайн

#4 Фев. 18, 2022 20:27:53

hendeman
Зарегистрирован: 2021-11-01
Сообщения: 3
Репутация: +  0  -
Профиль   Отправить e-mail  

Замыкания, вложенные функции

py.user.next
Для примера, возьмем первую часть Вашего кода и сравним с кодом ниже:
 def search_string(pattern, name):
     def f(string):
         return string in pattern
     return f(name)
searcher_john = 'John'
searcher_mary = 'Mary'
for s in ('Bob went to the shop',
           'I saw John near the car',
           'Her name was Mary'):
     if search_string(s, searcher_john):
         print('I see John in', repr(s))
     if search_string(s, searcher_mary):
         print('I see Mary in', repr(s))
Чем плох такой вариант?

Офлайн

#5 Фев. 19, 2022 01:04:15

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9873
Репутация: +  853  -
Профиль   Отправить e-mail  

Замыкания, вложенные функции

hendeman
Чем плох такой вариант?
Ну, я убираю цикл вообще и получаю короткий код
  
>>> def search_string(pattern):
...     def f(string):
...         return pattern in string
...     return f
... 
>>> def f():
...     searcher_john = search_string('John')
...     searcher_mary = search_string('Mary')
...     strings = ('Bob went to the shop',
...                'I knew Mary since 2007',
...                'I saw John near the car',
...                'I saw John near the shop',
...                'Her name was Mary')
...     print('I see John in', *map(repr, filter(searcher_john, strings)))
...     print('I see Mary in', *map(repr, filter(searcher_mary, strings)))
... 
>>> f()
I see John in 'I saw John near the car' 'I saw John near the shop'
I see Mary in 'I knew Mary since 2007' 'Her name was Mary'
>>>
Как видишь, тут замыкание передаётся в функцию filter(). Внутри функции filter() замыкание вызывается как функция.
А ты свою функцию сможешь как-то с искомым именем передать в другую функцию? Как ты их соединишь?



Отредактировано py.user.next (Фев. 19, 2022 01:23:25)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version