Подтвердить что ты не робот

Выход в 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

если работает, но кажется проводным. У кого есть идея?

спасибо,

4b9b3361

Ответ 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