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
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.
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.
A `def` can give you either an ordinary function or a generator. You can't have both 🤷♂️
> (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.