In python is there a way to check if a function is a “generator function” before calling it?
假设我有两个功能:
1 2 3 4 5 | def foo(): return 'foo' def bar(): yield 'bar' |
第一个是正态函数,第二个是生成函数。现在我想写一些这样的东西:
1 2 3 4 5 6 7 | def run(func): if is_generator_function(func): gen = func() gen.next() #... run the generator ... else: func() |
号
现在考虑以下情况:
1 2 3 4 5 | def goo(): if False: yield else: return |
调用
谢谢!
1 2 3 4 5 6 7 8 9 10 11 12 | >>> import inspect >>> >>> def foo(): ... return 'foo' ... >>> def bar(): ... yield 'bar' ... >>> print inspect.isgeneratorfunction(foo) False >>> print inspect.isgeneratorfunction(bar) True |
- 在新版本的Python 26
实际上,我只是wondering如何有用的这一假设的
1 2 3 4 5 6 7 8 9 10 11 | def foo(): return 'foo' def bar(): yield 'bar' def baz(): return bar() def quux(b): if b: return foo() else: return bar() |
你应该为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | >>> def foo(): ... return 'foo' ... >>> def bar(): ... yield 'bar' ... >>> import dis >>> dis.dis(foo) 2 0 LOAD_CONST 1 ('foo') 3 RETURN_VALUE >>> dis.dis(bar) 2 0 LOAD_CONST 1 ('bar') 3 YIELD_VALUE 4 POP_TOP 5 LOAD_CONST 0 (None) 8 RETURN_VALUE >>> |
正如你看到的,关键的区别是,bytecode为
我已经在这一decorator implemented?胡克斯的decorated / yielded价值函数返回。按:其基本
1 2 3 4 5 6 7 8 9 10 11 12 13 | import types def output(notifier): def decorator(f): def wrapped(*args, **kwargs): r = f(*args, **kwargs) if type(r) is types.GeneratorType: for item in r: # do something yield item else: # do something return r return decorator |
它的功能是decorator作品因为unconditionnaly回报价值:这是被称为,是测试。
编辑:Robert lujo以下的评论,我结束了与一些如:
1 2 3 4 5 6 7 8 9 10 11 12 | def middleman(f): def return_result(r): return r def yield_result(r): for i in r: yield i def decorator(*a, **kwa): if inspect.isgeneratorfunction(f): return yield_result(f(*a, **kwa)) else: return return_result(f(*a, **kwa)) return decorator |