Как / каково значение переменной во вложенной функции, для которой объявлено нелокальное значение?

def make_test_dice(*outcomes):
    """Return a die that cycles deterministically through OUTCOMES.

    >>> dice = make_test_dice(1, 2, 3)
    >>> dice()
    1
    >>> dice()
    2
    >>> dice()
    3
    >>> dice()
    1
    """
    assert len(outcomes) > 0, 'You must supply outcomes to make_test_dice'
    for o in outcomes:
        assert type(o) == int and o >= 1, 'Outcome is not a positive integer'
    index = len(outcomes) - 1
    print("Index1: ", index)
    def dice():
        nonlocal index 
        index = (index + 1) % len(outcomes)
        print("Index2: ", index)
        return outcomes[index]
    return dice

def main(): 
    foursided = make_test_dice(4,1,2)
    foursided()
    foursided()

if __name__ == "__main__": main()

Поэтому я понимаю, что после вызова make_test_dice, при вызове foursided он пропускает печать индекса index1 var и переходит к функции dice, поскольку это закрытие. Я понимаю, что нелокальные переменные относятся к переменным во вложенной области видимости, так что изменение var во вложенной функции изменит ее во внешней, но я не понимаю, как переменная индекса хранится внутри вложенной функции, потому что она нужен индекс значения при установке значения в dice(). Учитывая мои операторы печати, я верю, что это может быть предыдущее значение индекса, но я думал, что индекс исчезнет после того, как мы выйдем из локального фрейма функции make_test_dice.

1 ответ

Решение

Я понимаю, что после вызова make_test_dice, при вызове foursided он пропускает печать var index1 и переходит к функции dice,

Ничего не пропущено вообще - foursided IS "функция кости". Или, точнее, это функциональный объект, который был создан во время foursided = make_test_dice(4,1,2) звонок - каждый звонок make_test_dice() создает новую функцию "кости".

как это закрытие

Похоже, вы на самом деле не понимаете, что такое закрытие на самом деле.

Я понимаю, что нелокальные переменные относятся к переменным во внешней области видимости, так что изменение var во вложенной функции изменит ее во внешней, но я не понимаю, как переменная индекса хранится внутри вложенной функции

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

def show_closure(func):
    print(func.__closure__)
    for cell in func.__closure__:
        print(cell.cell_contents)


foursided = make_test_dice(4,1,2)
for i in range(4):
    show_closure(foursided)
    foursided()
Другие вопросы по тегам