如何调用 yield (python 2.7) 的函数

How to call the function that yields (python 2.7)

我有两个函数 func1 和 func2,它们是 func0 的特定实现,会产生结果:

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

我应该如何在 "specific" 函数中引用 func0 以使它们产生结果? return可以吗?

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

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

在Python 3.3+中,正常的方式是使用yield 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.

然而,对于 Python 2.7,这是不可能的。这里有一个替代方案:

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()))

输出

4
9

您正在从函数中返回生成器。 您需要阅读有关生成器的内容,它并不长,无论如何这里有一种使用它的方法:

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

或 res = next(gen) # python 2 和 3

我会这样做:

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

你可以看看 partial 那里。正如我在评论中所说,它本质上是克隆您的函数,并且已经设置了一些必需的参数。


所以如果 func0 产生 那么它的部分 func1func2.

如果您使用 return,那么 func1 将 return 生成器即 func0。或者,如果您使用 yield from,那么包装函数本身就变成了一个生成器,从 func0 中生成各个项目。两种情况下生成的元素相同。

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

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

注意 func1 return 是 func0 生成器,而 func2 return 是 func2 生成器。

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

注意 yield from 是在 Python 3 中引入的。在 Python 2 中,您可以通过循环 yield 来实现相同的效果。

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