如何在python中装饰生成器

kas*_*sky 13 python generator decorator

所以,我定义了一个简单的生成器:

def gen1(x):
    if x <= 10:
        yield x
        for v in gen1(x + 1):
            yield v
Run Code Online (Sandbox Code Playgroud)

基本上,我想装饰它,所以它返回所有值,但最后:

def dec(gen):

    def new_gen(x):
        g = gen(x)
        value = g.next()
        for v in g:
            yield value
            value = v

    return new_gen
Run Code Online (Sandbox Code Playgroud)

现在,如果我重新定义gen1

@dec
def gen1(x):
    ...

for i in gen1(1):
    print i    # Nothing printed
Run Code Online (Sandbox Code Playgroud)

但如果我使用:

some_gen = dec(gen1)

for i in some_gen(1):
    print i    # Prints 1 to 9, as needed
Run Code Online (Sandbox Code Playgroud)

为什么我的装饰师不起作用,我该如何解决?

eca*_*mur 6

您的递归调用gen1也取决于您的装饰器,因此装饰器会消耗掉所有东西.

最简单的解决方法是以非递归样式编写生成器,或者封装递归:

封装:

@dec
def gen1(x):
    def inner(x):
        if x <= 10:
            yield x
            for v in inner(x + 1):
                yield v
    return inner(x)
Run Code Online (Sandbox Code Playgroud)

非递归:

@dec
def gen1(x):
    for v in range(x, 11):
        yield v
Run Code Online (Sandbox Code Playgroud)