Общие и локализованные переменные в замыканиях Python - PullRequest
0 голосов
/ 05 июля 2018

Замыкания в Python ведут себя как бы странно. Рассмотрим следующий фрагмент кода, где я попытался создать список замыканий на основе foo двумя способами: в bad_closure замыкания создаются «на лету», а в good_closure замыкания создаются помощником. функция:

def foo(d):
    return d + 1

def bad_closure():
    ''' shares resources implicitly '''

    # list of 5 closures
    # `i` is shared between all closures
    cls = [lambda : foo(i) for i in range(5)]
    return cls

def good_closure():
    ''' no resource sharing '''

    def mk_cl(i):
        ''' helper to make a closure'''
        c_ = lambda : foo(i)
        return c_

    # list of 5 closures
    # each closure has its own `i`
    cls = [mk_cl(i) for i in range(5)]
    return cls

#--- TEST ---
bs = bad_closure()
print([f() for f in bs]) # output: [5, 5, 5, 5, 5]

gs = good_closure()
print([f() for f in gs]) # output: [1, 2, 3, 4, 5]

Результаты поразительно разные. Кажется, что в bad_closure замыкания принимают фиксированный i каждый, но все они share тот же i, который обновляется при каждой итерации (и, наконец, принимает значение 5)! Напротив, в good_closure, i являются отдельными - как я ожидаю.

Я бы хотел посмотреть, что происходит за кулисами и почему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...