【问题标题】:How to check if a python function is a Tornado generator如何检查 python 函数是否是 Tornado 生成器
【发布时间】:2016-06-30 03:00:05
【问题描述】:

给定一个函数 foobar 我如何检查它是否是 Tornado 预期的生成器?

In [1]: from tornado import gen

In [2]: @gen.coroutine
   ...: def foobar():
   ...:     print 'boom'
   ...:

我找不到任何属性,这可能表明它被 gen.coroutine 正确装饰

【问题讨论】:

  • 也许在foobar.func_code.co_filename
  • 然后在那里搜索“gen”这个词?看起来很老套,但比我发现的任何东西都更接近
  • 看起来很老套和蹩脚,这就是我评论而不是回答的原因。但我在 python2 中找不到更好的东西
  • 'TracebackFuture' in foobar.func_code.co_names 仍然很老套,但更接近幸福

标签: python tornado python-decorators


【解决方案1】:

我找不到令人满意的方法来从已经存在的装饰器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)

【讨论】:

  • :( 是的,但我不想要求我的图书馆的用户使用自定义装饰器......尽管从我的在线搜索来看,这正在成为最合理的解决方案
【解决方案2】:

没有很好的方法来检测这一点,即使 @coroutine 被修改为设置某些属性,在使用多个装饰器的情况下也会失败(例如,处理程序可能同时使用 @authenticated@coroutine 进行装饰,而@authenticated 装饰器的包装器将隐藏@coroutine 添加的任何内容)

此外,许多函数(包括核心 Tornado 方法,如AsyncHTTPClient.fetchIOStream 的大多数方法)在技术上不是协同程序,但它们可以像被调用一样被调用。在大多数情况下,最重要的问题不是“这是协程吗”,而是“这是否返回 Future”。如果不调用该函数,则无法在 Python 中确定这一点。

【讨论】:

  • 我最终编写了自己的装饰器,它用 tornado 的协程装饰了函数,并添加了一个我可以检查的标志。不理想,但为我提供了一种在函数被传递时进行各种健全性检查的方法,执行函数之前。
猜你喜欢
  • 2013-05-21
  • 2013-07-15
  • 2016-03-10
  • 2014-04-17
  • 2018-11-08
  • 2020-05-25
  • 2017-07-31
  • 2020-03-23
相关资源
最近更新 更多