diff --git a/translations/README-ru.md b/translations/README-ru.md index 5f3f4bb..638536d 100644 --- a/translations/README-ru.md +++ b/translations/README-ru.md @@ -1544,3 +1544,69 @@ def some_func(val): - В Python 3.8+ yield внутри списочных выражений больше не допускается и выдает `SyntaxError`. --- + + +### ▶ Yield from возвращает... * + +1\. + +```py +def some_func(x): + if x == 3: + return ["wtf"] + else: + yield from range(x) +``` + +**Результат (> 3.3):** + +```py +>>> list(some_func(3)) +[] +``` + +Куда исчезло `"wtf"`? Это связано с каким-то особым эффектом `yield from`? Проверим это. + +2\. + +```py +def some_func(x): + if x == 3: + return ["wtf"] + else: + for i in range(x): + yield i +``` + +**Результат:** + +```py +>>> list(some_func(3)) +[] +``` + +То же самое, это тоже не сработало. Что происходит? + +#### 💡 Объяснение: + ++ С Python 3.3 стало возможным использовать оператор `return` в генераторах с возвращением значения (см. [PEP380](https://www.python.org/dev/peps/pep-0380/)). В [официальной документации](https://www.python.org/dev/peps/pep-0380/#enhancements-to-stopiteration) говорится, что + +> "... `return expr` в генераторе вызывает исключение `StopIteration(expr)` при выходе из генератора." + ++ В случае `some_func(3)` `StopIteration` возникает в начале из-за оператора `return`. Исключение `StopIteration` автоматически перехватывается внутри обертки `list(...)` и цикла `for`. Поэтому два вышеприведенных фрагмента приводят к пустому списку. + ++ Чтобы получить `["wtf"]` из генератора `some_func`, нужно перехватить исключение `StopIteration`. + + ```py + try: + next(some_func(3)) + except StopIteration as e: + some_string = e.value + ``` + + ```py + >>> some_string + ["wtf"] + ``` + +---