- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
比如说,我有一个函数,它用 gen.engine 包裹起来以“理顺”回调链,也就是说,这样代码看起来是同步的/线性的/其他的。
函数,然后看起来像这样
@gen.engine
def func():
...
yield gen.Task(...)
...
yield gen.Task(...)
等等。我明白,我绝对可以在 yield
周围使用 try/except 来捕获函数中发生的异常,这些异常由 gen.Task
包装。如果我需要将函数 func
本身包装在另一个函数中以(这是实际用例)捕获 func
中的所有“未捕获”异常而不引入“丑陋”怎么办(对..)try/except,这将跨越整个func
?
我想出了这个:
@gen.engine
def func(..., callback):
...
callback()
@gen.engine
def outer():
try:
yield gen.Task(func)
except Exception as e:
# Log the exception
# Stop ioloop (or something)
这为 func
增加了一点通用性,但在 func
中引入了一个额外的参数和一些人工逻辑。
还有其他方法吗?请注意,“紧急异常捕获”或多或少是出于此问题目的的人为用例(这可能可以通过其他方式完成),我正在寻找的是调用那些 tornado.gen 的正确方法。来自另一个函数的引擎包装函数。
编辑:愚蠢的我,我应该提到我仅限于 tornado 2.x!
最佳答案
@gen.coroutine
是 Tornado 3 的新特性。来自 http://www.tornadoweb.org/en/stable/releases/v3.0.0.html :
New decorator @gen.coroutine is available as an alternative to @gen.engine. It automatically returns a Future, and within the function instead of calling a callback you return a value with raise gen.Return(value) (or simply return value in Python 3.3).
来自文档(http://www.tornadoweb.org/en/stable/gen.html#tornado.gen.coroutine):
Functions with this decorator return a Future. Additionally, they may be called with a callback keyword argument, which will be invoked with the future’s result when it resolves. If the coroutine fails, the callback will not be run and an exception will be raised into the surrounding StackContext. The callback argument is not visible inside the decorated function; it is handled by the decorator itself.
因此没有理由担心回调,也没有必要将函数包装到 tornado.gen.Task()
中。链接现在很容易:
#!/usr/bin/python
# -*- coding: utf-8 -*-
import logging
import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
import tornado.gen
from tornado.options import define, options
define("port", default=8000, help="run on the given port", type=int)
class MainHandler(tornado.web.RequestHandler):
@tornado.gen.coroutine
def outer(self):
logging.info('outer starts')
yield self.inner()
yield self.inner()
logging.info('outer ends')
raise tornado.gen.Return('hello')
@tornado.gen.coroutine
def inner(self):
logging.info('inner runs')
@tornado.web.asynchronous
@tornado.gen.coroutine
def get(self):
res = yield self.outer()
self.write(res)
if __name__ == "__main__":
tornado.options.parse_command_line()
app = tornado.web.Application(handlers=[(r"/", MainHandler)])
http_server = tornado.httpserver.HTTPServer(app)
http_server.listen(options.port)
tornado.ioloop.IOLoop.instance().start()
输出:
$ python test.py
[I 130529 03:18:35 test:21] outer starts
[I 130529 03:18:35 test:29] inner runs
[I 130529 03:18:35 test:29] inner runs
[I 130529 03:18:35 test:24] outer ends
[I 130529 03:18:35 web:1514] 200 GET / (127.0.0.1) 1.48ms
从 Python 3.3 开始,无需使用 gen.Result()
,简单的 return
即可。在旧版本中,会出现 'return' with argument inside generator
错误。
另外,检查:https://github.com/facebook/tornado/issues/759
更新:
至于 Tornado 2.x,我认为没有简单的方法来隐藏回调。文档状态:
In most cases, functions decorated with engine should take a callback argument and invoke it with their result when they are finished. One notable exception is the RequestHandler get/post/etc methods, which use self.finish() in place of a callback argument.
所以我担心这些是不可避免的。示例:
class MainHandler(tornado.web.RequestHandler):
@tornado.web.asynchronous
@tornado.gen.engine
def get(self):
res = yield tornado.gen.Task(self.outer)
self.write(res)
self.finish()
def inner(self, callback):
logging.info('inner runs')
callback()
@tornado.gen.engine
def outer(self, callback):
logging.info('outer starts')
yield tornado.gen.Task(self.inner)
yield tornado.gen.Task(self.inner)
logging.info('outer ends')
callback("hello")
关于python - 用另一个函数包装 tornado.gen.engine-wrapped 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16785045/
正在尝试创建一个 python 包。似乎有效,但我收到警告。我的 setup.py 是: #! /usr/bin/env python from distutils.core import setup
我导入了一个数据类型 X ,定义为 data X a = X a 在本地,我定义了一个通用量化的数据类型,Y type Y = forall a. X a 现在我需要定义两个函数, toY 和 fro
我似乎无法让编译器让我包装 Tokio AsyncRead: use std::io::Result; use core::pin::Pin; use core::task::{Context, Po
我有两个函数“a”和“b”。当用户上传文件时,“b”被调用。 “b”重命名文件并返回新文件名。之后应该编辑该文件。像这样: def a(): edits file def b(): r
我使用 Entity Framework 作为我的 ORM,我的每个类都实现了一个接口(interface),该接口(interface)基本上表示表结构(每个字段一个只读属性)。这些接口(inter
有没有办法打开一个程序,通常会打开一个新的jframe,进入一个现有的jframe? 这里是解释,我下载了一个java游戏,其中一个是反射游戏,它在一个jframe中打开,框架内有一堆子面板,我想要做
我想要下面的布局 | AA BBBBBBB | 除非没有足够的空间,在这种情况下 | AA | | BBBBBBB | 在这种情况下,A 是复选框,B 是复选框旁边的 Text
我正在尝试以不同的方式包装我的网站,以便将背景分为 2 部分。灰色部分是主要背景,还有白色部分,它较小并包装主要内容。 基本上我想要this看起来像this . 我不太确定如何添加图像来创建阴影效果,
我正在使用 : 读取整数文件 int len = (int)(new File(file).length()); FileInputStream fis = new FileInputStream(f
我使用 maven 和 OpenJDK 1.8 打包了一个 JavaFX 应用程序我的 pom.xml 中的相关部分: maven-assembly-plugin
我正在使用两个不同的 ItemsControl 来生成一个按钮列表。
我有一个情况,有一个变量会很方便,to , 可以是 TimerOutput或 nothing .我有兴趣提供一个采用与 @timeit 相同参数的宏来自 TimerOutputs(例如 @timeit
我正在尝试包装一个名为 content 的 div与另一个具有不同背景的 div。 但是,当将“margin-top”与 content 一起使用时div,似乎包装 DIV 获得了边距顶部而不是 co
文档不清楚,它似乎允许包装 dll 和 csproj 以在 Asp.Net Core 5 应用程序中使用。它是否允许您在 .Net Core 5 网站中使用针对 .Net Framework 4.6
我被要求开发一个层,该层将充当通用总线,而不直接引用 NServiceBus。到目前为止,由于支持不引人注目的消息,这并不太难。除了现在,我被要求为 IHandleMessages 提供我们自己的定义
我正在尝试包装 getServersideProps使用身份验证处理程序函数,但不断收到此错误:TypeError: getServerSideProps is not a function我的包装看
我有一个项目,它在特定位置(不是/src/resources)包含资源(模板文件)。我希望在运行 package-bin 时将这些资源打包。 我看到了 package-options 和 packag
我正在寻找打印从一系列对象中绘制的 div。我可以通过使用下面的管道语法来实现这一点。 each i, key in faq if (key == 0) |
我在 Meteor.js“main.js - Server”中有这个方法。 Meteor.methods({ messageSent: function (message) { var a
我注意到,如果我的自定义Polymer 1.x元素的宽度比纸张输入元素上的验证错误消息的宽度窄,那么错误将超出自定义元素的右边界。参见下图: 有没有一种机制可以防止溢出,例如在到达自定义元素的边界时自
我是一名优秀的程序员,十分优秀!