给定一个函数foobar
我怎样才能检查它是Tornado所期望的生成器?
In [1]: from tornado import gen
In [2]: @gen.coroutine
...: def foobar():
...: print 'boom'
...:
我无法找到任何属性,这可能表明它已被gen.coroutine
答案 0 :(得分:4)
没有好方法可以检测到这一点,即使@coroutine
被修改为设置某个属性,在使用多个装饰器的情况下也会失败(例如,处理程序可能同时使用@authenticated
进行修饰和@coroutine
,@authenticated
装饰器的包装器将隐藏@coroutine
添加的任何内容
此外,许多函数(包括AsyncHTTPClient.fetch
等核心Tornado方法或IOStream
的大多数方法)在技术上并不是协同程序,但它们可以像它们一样被调用。在大多数情况下,最重要的问题不是"这是一个协程"但是"这会返回Future
"。没有调用函数就无法在Python中确定这一点。
答案 1 :(得分:2)
我找不到一种令人满意的方法来从现有的装饰器gen.coroutine
中反省它。
我不确定这对你是否有用,但是如果你能控制特定的装饰器本身,那么你可以选择简单地将属性添加到函数本身。
>>> def my_gen_coroutine(f):
... f = gen.coroutine(f)
... f.is_a_tornado_generator = True
... return f
...
>>> @my_gen_coroutine
... def foobar():
... print 'boom'
...
>>> foobar.is_a_tornado_generator
True
>>> foobar()
boom
<tornado.concurrent.Future at 0x1397d50>
当然,当您不知道属性是否存在时,您将使用getattr(some_function, 'is_a_tornado_generator', False)
。