fanny
fanny

Reputation: 1441

How to call the function that yields (python 2.7)

I have two functions func1 and func2 that are specific implementations of func0 that YIELDS its result:

def func0(parameter, **kwargs):
    #do sth with kwargs and parameter
    yield result # result is html

how should I refer to func0 inside the "specific" functions to make them yield their results? Is return ok?

def func1(**kwargs):
    return func0(parameter=1, **kwargs)

def func2(**kwargs):
    return func0(parameter=2, **kwargs)

Upvotes: 2

Views: 3340

Answers (4)

tobias_k
tobias_k

Reputation: 82899

If you use return, then func1 will return the generator that is func0. Alternatively, if you use yield from, then the wrapping function becomes a generator itself, yielding the individual items from func0. The yielded elements are the same in both cases.

def func1(**kwargs):
    return func0(parameter=1, **kwargs)

def func2(**kwargs):
    yield from func0(parameter=1, **kwargs)

Note how func1 returns a func0-generator, while func2 returns a func2-generator.

>>> func1()
<generator object func0 at 0x7fe038147ea0>
>>> func2()
<generator object func2 at 0x7fe038147ee8>
>>> list(func1()) == list(func2())
True

Note that yield from was introduced in Python 3. In Python 2, you can achieve the samy by yielding from a loop.

def func2(**kwargs):
    for x in func0(parameter=1, **kwargs):
        yield x

Upvotes: 3

Ma0
Ma0

Reputation: 15204

This is how i would do it:

def func0(a):
    yield a**2

from functools import partial

func1 = partial(func0, a=1)
func2 = partial(func0, a=10)
print(next(func1()))  # prints 1
print(next(func2()))  # prints 100

You can take a look at partial there. As i said in the comments it essentially clones your function with some of its required parameters already set.


So if func0 yields so do its partials func1 and func2.

Upvotes: 1

Israel Unterman
Israel Unterman

Reputation: 13510

You are returning generators from the functions. You need to read about generator, it's not long, anyway is here a way to use it:

gen = func1(args...)
res = gen.next()  # python 2

or res = next(gen) # python 2 and 3

Upvotes: 1

Tagc
Tagc

Reputation: 9076

In Python 3.3+, the normal way would be to use yield from. From the documentation:

PEP 380 adds the yield from expression, allowing a generator to delegate part of its operations to another generator. This allows a section of code containing yield to be factored out and placed in another generator. Additionally, the subgenerator is allowed to return with a value, and the value is made available to the delegating generator.

For Python 2.7 that's not possible, however. Here's an alternative that works instead:

def base_squared_generator(parameter):
    yield parameter ** 2


def two_squared_generator():
    yield next(base_squared_generator(parameter=2))


def three_squared_generator():
    yield next(base_squared_generator(parameter=3))


print(next(two_squared_generator()))
print(next(three_squared_generator()))

Output

4
9

Upvotes: 5

Related Questions