在Python中包装生成器函数

eri*_*ich 5 python generator decorator

我正在编写一些遍历可能具有循环引用的结构的代码.我没有在递归函数的开头显式地进行检查,而是认为我会创建一个装饰器,它不允许使用相同的参数多次调用函数.

以下是我提出的建议.在编写时,这将尝试迭代Nonetype并引发异常.我知道我可以通过返回说出一个空列表来修复它,但我想要更优雅.有没有办法从装饰器内判断被装饰的函数是否是生成函数?这样我可以有条件地提高StopIteration,如果它是一个生成器,或者只返回None否则.

previous = set()
def NO_DUPLICATE_CALLS(func):
    def wrapped(*args, **kwargs):
        if args in previous:
            print 'skipping previous call to %s with args %s %s' % (func.func_name, repr(args), repr(kwargs))
            return
        else:
            ret = func(*args, **kwargs)
            previous.add(args)
            return ret
    return wrapped

@NO_DUPLICATE_CALLS
def foo(x):
    for y in x:
        yield y

for f in foo('Hello'):
    print f

for f in foo('Hello'):
    print f
Run Code Online (Sandbox Code Playgroud)

JAB*_*JAB 5

好的,看看这个:

>>> from inspect import isgeneratorfunction
>>> def foo(x):
...    for y in x:
...        yield y
...
>>> isgeneratorfunction(foo)
True
Run Code Online (Sandbox Code Playgroud)

但这需要Python 2.6或更高版本.