Выход в Python
в соответствии с ответом на этот question, выход break в С# эквивалентен возврату в python. в нормальном случае "возврат" действительно останавливает генератор. Но если ваша функция ничего не делает, кроме возврата, вы получите None, а не пустой итератор, который возвращается с помощью прерывания yield в С#
def generate_nothing():
return
for i in generate_nothing():
print i
вы получите TypeError: объект "NoneType" не является итерируемым.
но если я добавлю никогда нерабочую доходность перед возвратом, эта функция вернет то, что я ожидаю.
def generate_nothing():
if False: yield None
return
если работает, но кажется проводным. У кого есть идея?
спасибо,
Ответы
Ответ 1
Хорошим способом справиться с этим является повышение StopIteration, что и возникает, когда вашему итератору ничего не остается, и вызывается next()
. Это также изящно выйдет из цикла for, и ничего внутри цикла не будет выполнено.
Например, учитывая кортеж (0, 1, 2, 3)
, я хочу получить перекрывающиеся пары ((0, 1), (1, 2), (2, 3))
. Я мог бы сделать это так:
def pairs(numbers):
if len(numbers) < 2:
raise StopIteration
for i, number in enumerate(numbers[1:]):
yield numbers[i], number
Теперь pairs
безопасно обрабатывает списки с 1 номером или меньше.
Ответ 2
def generate_nothing():
return
yield
Ответ 3
def generate_nothing():
return iter([])
Ответ 4
Самое смешное, что обе функции имеют один и тот же байт-код. Вероятно, есть флаг, который устанавливает generator
, когда компилятор байтового кода находит ключевое слово yield
.
>>> def f():
... return
>>> def g():
... if False: yield
#in Python2 you can use 0 instead of False to achieve the same result
>>> from dis import dis
>>> dis(f)
2 0 LOAD_CONST 0 (None)
3 RETURN_VALUE
>>> dis(g)
2 0 LOAD_CONST 0 (None)
3 RETURN_VALUE