Skip to content

Commit

Permalink
New snippet: yielding from... return!
Browse files Browse the repository at this point in the history
  • Loading branch information
scidam committed Sep 13, 2019
1 parent 9f5dbbe commit cedbfba
Showing 1 changed file with 59 additions and 0 deletions.
59 changes: 59 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ So, here we go...
- [▶ Be careful with chained operations](#-be-careful-with-chained-operations)
- [▶ Name resolution ignoring class scope](#-name-resolution-ignoring-class-scope)
- [▶ Needle in a Haystack](#-needle-in-a-haystack)
- [▶ Yielding from... return!](#-yielding-from-return)
- [Section: The Hidden treasures!](#section-the-hidden-treasures)
- [▶ Okay Python, Can you make me fly? *](#-okay-python-can-you-make-me-fly-)
- [▶ `goto`, but why? *](#-goto-but-why-)
Expand Down Expand Up @@ -1883,6 +1884,64 @@ tuple()

---

### ▶ Yielding from... return!

1\.
```py
def func(k):
if k == 3:
return ["A string..."]
else:
yield from range(k)
```

**Output:**
```py
>>> list(func(3)) # expected: ["A string..."]
[]
```

The same behavior is true if we rewrite `yield from` as a for loop.

2\.
```py
def func(k):
if k == 3:
return ["A string..."]
else:
for j in range(k):
yield j
```

**Output:**
```py
>>> list(func(3)) # expected: ["A string..."]
[]
```

#### 💡 Explanation:

Starting from Python 3.3+ it became possible to use return statement
with values inside generators ([PEP380](https://www.python.org/dev/peps/pep-0380/)). The [official doc](https://www.python.org/dev/peps/pep-0380/#enhancements-to-stopiteration) says that "... `return expr` in a generator causes `StopIteration(expr)` to be raised upon exit from the generator."

So, to get `["A string..."]` from the generator `func` we need to catch `StopIteration`, e.g.:

```py
try:
next(func(3))
except StopIteration as e:
string = e.value
```

```py
>>> string
['A string...']
```

Note that `list(...)` automatically catches `StopIteration`. In case of `func(3)` `StopIteration` raises at the beginning because of `return` statement. Therefore, `list(func(3))` results in an empty list.

---

---


Expand Down

0 comments on commit cedbfba

Please sign in to comment.