Is it good practice to mix yield and return statements in python?

Only in Python 3 it is syntactically possible to have return value and yield in the same function, in Python 2 it will result in:

SyntaxError: 'return' with argument inside generator

In Python 3 return value inside a generator is actually a syntactic sugar for raise StopIteration(value), which is also supported by the yield from clause:

def f():
    yield from iter('123')
    return 'ok'

def g():
    message = yield from f()
    print('Message:', message)

In [1]: list(g)
Message: ok
Out[1]: ['1', '2', '3']

So, this construct does not do what you expect it to. Besides, it does not seem a very good (“pythonic”) idea to vary the return type (or, rather, interface) of a function based on the argument value. That may be a matter of taste, though, here is what Guido van Rossum says in his interview in the book Masterminds of Programming:

I have a few personal pet peeves: first of all, and this is specific to dynamic languages, don’t make the return type of a method depend on the value of one of the arguments; otherwise it may be hard to understand what’s returned if you don’t know the relationship—maybe the type-determining argument is passed in from a variable whose content you can’t easily guess while reading the code.

Leave a Comment