如何检查函数 foobar
是否是 Tornado 所需的生成器?
In [1]: from tornado import gen
In [2]: @gen.coroutine
...: def foobar():
...: print 'boom'
...:
我无法找到任何属性,表明它被一个gen.coroutine
正确装饰了。
如何检查函数 foobar
是否是 Tornado 所需的生成器?
In [1]: from tornado import gen
In [2]: @gen.coroutine
...: def foobar():
...: print 'boom'
...:
我无法找到任何属性,表明它被一个gen.coroutine
正确装饰了。
目前还没有很好的方法来检测这个问题,即使将@coroutine
修改为设置某些属性,在使用多个装饰器(例如处理程序可能同时使用@authenticated
和@coroutine
装饰器,而@authenticated
装饰器的包装将隐藏@coroutine
添加的任何内容)的情况下,这种方法也会失败。
此外,许多函数(包括核心Tornado方法,如AsyncHTTPClient.fetch
或IOStream
的大多数方法)在技术上并不是协程,但可以像协程一样调用。在大多数情况下,最重要的问题不是“这是一个协程吗”,而是“它是否返回一个Future
”。在Python中没有办法在不调用函数的情况下确定这一点。
我无法找到一种令人满意的方式来自现有的装饰器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)
。
foobar.func_code.co_filename
中。 - wim'TracebackFuture' in foobar.func_code.co_names
还是有点瑕疵,但更接近于完美。 - Mikhail