Есть два «лучших» / более Pythonic способа сделать это на Python 2.x, чем использовать контейнер просто для того, чтобы обойти отсутствие нелокального ключевого слова.
Тот, который вы упомянули в комментарии в своем коде - привязка к локальной переменной. Есть еще один способ сделать это:
Использование аргумента по умолчанию
def make_incrementer(start):
def closure(start = start):
while True:
yield start
start += 1
return closure
x = make_incrementer(100)
iter = x()
print iter.next()
В этом есть все преимущества локальной переменной без дополнительной строки кода. Это также происходит в строке x = make_incrememter(100)
, а не в строке iter = x()
, что может иметь или не иметь значения в зависимости от ситуации.
Вы также можете использовать метод «на самом деле не присваивать ссылочной переменной» более элегантным способом, чем использование контейнера:
Использование атрибута функции
def make_incrementer(start):
def closure():
# You can still do x = closure.start if you want to rebind to local scope
while True:
yield closure.start
closure.start += 1
closure.start = start
return closure
x = make_incrementer(100)
iter = x()
print iter.next()
Это работает во всех последних версиях Python и использует тот факт, что в этой ситуации у вас уже есть объект, имя которого вы можете использовать для ссылок на атрибуты - нет необходимости создавать новый контейнер только для этой цели .