Alexey Vyskubov’s Post

More fun with dark corners of Python (yeah, this language is so easy to learn). Consider the following function: >>> def f(x): ... if x == 42: ... return x ... else: ... yield from([x]) When you call it with an argument not equal to 42, this is a generator alright: >>> list(f(1)) [1] Here f yielding from list [x] for x equal to 1, so no big surprise in the answer. But: >>> list(f(42)) [] Where is my number? Why don't I get syntax error? (Try list(42).) The reason is as following: - "yield from" tells Python that "f" is a generator - Python documentation says that "return val" in a generator is equivalent to "raise StopIteration(val)". And indeed: >>> try: ... next(f(42)) ... except StopIteration as ex: ... print(ex.value) ... 42 Here is my 42. #python #gotcha

> (yeah, this language is so easy to learn) This is not a real problem. I'll write an essay about it one day, but in a nutshell, present day Python is aiming at two (largely non-overlapping) demographics. One is not-really-developers (i.e. researchers, analysts, data scientists, sysadmins etc) who use Python for rapid prototyping, which is one area where it shines brightly. The other is well-actually-developers who clean up the mess made by the other group. The latter are conditioned to look at a function that combines a "return value" with a "yield" and immediately see that something isn't right here. The former just pass around lists and don't care, worry, or know about yields, generators, and such.

Why your function is dual either int or list? Your type system and compiler should capture this at compile time!

C#/F# have generators, but will fail to compile if you try an mix results. As Forest Gump might say "Python is like a box of chocolates..."

Well. To be honest, the combination of 'return' and 'yield from' in the same function looks weird right away. I mean that it will be caught in code review. So this situation is not that dangerous.

Like
Reply

This "cleverness" of Python is precisely why I shifted to Go for wherever I previously used Python. Your code is so far from obvious, and that's a critique of the language, not you. It is obviously the point of the post. Even with an explanation, I would need time to sit and look at the code to make sure I fully understood the execution.

Like
Reply

A `def` can give you either an ordinary function or a generator. You can't have both 🤷♂️

See more comments

To view or add a comment, sign in

Explore content categories