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

I would really like to have the following behavior:

def foo(bar=None): if bar: return other_function(other_thing[bar]) else: for i in other_thing: yield other_function(i) 

The idea is that the function can then be used as a generator to assemble all instances, or it can be used to return a specific instance. Is this a good way to do this in Python? If not, is there a better way.

+4
source share
1 answer

Only in Python 3 syntax may have a return value , and yield the same functions in Python 2 will lead to:

 SyntaxError: 'return' with argument inside generator 

The Python 3 return value inside the generator is actually a syntactic sugar to raise StopIteration(value) , which also supports the yield from :

 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'] ) 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 design does not do what you expect. In addition, it is not very good ( "pitonskoy") the idea to change the return type (or, rather, the interface) function based on the value of the argument. It may be a matter of taste, but that's what says Guido van Rossum in an interview in the book "programming ability":

I have several personal pets: firstly, and this is typical for dynamic languages, do not make the return type of the method dependent on the value of one of the arguments; otherwise it can be difficult to understand that back, if you do not know the relationship - perhaps an argument that defines the type, it is transmitted from the variable, which you can not easily guess the contents of the reading code.

+7
source

All Articles