在 Tornado 协程中引发异常或 return gen.Return 对象
Raise exception or return gen.Return object in Tornado coroutine
我们有一个 Python 2 项目,我们在其中积极使用协程。我们找不到任何关于协程内部异常处理的指南。
例如, Tornado 的首席开发人员提到 coroutines should never raise an exception
,但不清楚原因。看起来这种方法有效并在 Tornado.web 本身中大量使用:
https://github.com/tornadoweb/tornado/blob/master/demos/blog/blog.py#L180
class AuthCreateHandler(BaseHandler):
def get(self):
self.render("create_author.html")
@gen.coroutine
def post(self):
if self.any_author_exists():
raise tornado.web.HTTPError(400, "author already created")
hashed_password = yield executor.submit(
bcrypt.hashpw, tornado.escape.utf8(self.get_argument("password")),
bcrypt.gensalt())
tornado.web.HTTPError 只是扩展基础 Exception class。此外,此处的讨论 https://github.com/tornadoweb/tornado/issues/759#issuecomment-91817197 表明在协程内部引发异常是合适的。
还有 here,活跃的 Tornado 贡献者建议引发异常是好的:
class PostHandler(tornado.web.RequestHandler):
@gen.coroutine
def get(self, slug):
post = yield db.posts.find_one({'slug': slug})
if not post:
raise tornado.web.HTTPError(404)
self.render('post.html', post=post)
在 Tornado 协同程序中引发异常是否有任何缺点,或者我们应该 raise gen.Return(exception_object)
?
在Python 2、只用raise gen.Return(value)
到return一个正常值,不抛异常。它完全等同于 Python 中协程中的 return value
3.
要从协程中引发异常,正常的 raise Exception()
是正确的。协程的美妙之处在于它们的异常处理语义与常规函数几乎相同。
在协同程序中引发异常是完全正常的。当我说 "coroutines should never raise an exception" 时,我指的是当您 调用 一个没有 yield
或 await
的协程时会发生什么:异常被捕获并保持到协同程序的 return 值是 yielded
或 awaited
。
我们有一个 Python 2 项目,我们在其中积极使用协程。我们找不到任何关于协程内部异常处理的指南。
例如,coroutines should never raise an exception
,但不清楚原因。看起来这种方法有效并在 Tornado.web 本身中大量使用:
https://github.com/tornadoweb/tornado/blob/master/demos/blog/blog.py#L180
class AuthCreateHandler(BaseHandler):
def get(self):
self.render("create_author.html")
@gen.coroutine
def post(self):
if self.any_author_exists():
raise tornado.web.HTTPError(400, "author already created")
hashed_password = yield executor.submit(
bcrypt.hashpw, tornado.escape.utf8(self.get_argument("password")),
bcrypt.gensalt())
tornado.web.HTTPError 只是扩展基础 Exception class。此外,此处的讨论 https://github.com/tornadoweb/tornado/issues/759#issuecomment-91817197 表明在协程内部引发异常是合适的。
还有 here,活跃的 Tornado 贡献者建议引发异常是好的:
class PostHandler(tornado.web.RequestHandler):
@gen.coroutine
def get(self, slug):
post = yield db.posts.find_one({'slug': slug})
if not post:
raise tornado.web.HTTPError(404)
self.render('post.html', post=post)
在 Tornado 协同程序中引发异常是否有任何缺点,或者我们应该 raise gen.Return(exception_object)
?
在Python 2、只用raise gen.Return(value)
到return一个正常值,不抛异常。它完全等同于 Python 中协程中的 return value
3.
要从协程中引发异常,正常的 raise Exception()
是正确的。协程的美妙之处在于它们的异常处理语义与常规函数几乎相同。
在协同程序中引发异常是完全正常的。当我说 "coroutines should never raise an exception" 时,我指的是当您 调用 一个没有 yield
或 await
的协程时会发生什么:异常被捕获并保持到协同程序的 return 值是 yielded
或 awaited
。