【问题标题】:How can I kill off a Python web app on GAE early following a redirect?如何在重定向后尽早关闭 GAE 上的 Python Web 应用程序?
【发布时间】:2011-03-01 10:36:36
【问题描述】:

免责声明:从 PHP 背景开始对 Python 完全陌生

好的,我在 Google App Engine 上使用 Python 和 Google 的 webapp 框架。

我有一个要导入的函数,因为它包含需要在每个页面上处理的内容。

def some_function(self):
    if data['user'].new_user and not self.request.path == '/main/new':
        self.redirect('/main/new')

当我调用它时它工作正常,但我如何确保应用程序在重定向后被终止。我不想要任何其他处理。例如我会这样做:

class Dashboard(webapp.RequestHandler):
    def get(self):
        some_function(self)
        #Continue with normal code here
        self.response.out.write('Some output here')

我想确保一旦在 some_function() 中进行了重定向(工作正常),重定向之后的 get() 函数中不会进行任何处理,也不会输出“此处的某些输出”。

我应该注意什么才能使这一切正常工作?我不能只退出脚本,因为 webapp 框架需要运行。

我意识到对于 Python 应用程序,我很可能只是以完全错误的方式做事,所以任何指导都会有很大帮助。希望我已经正确解释了自己,并且有人能够指出我正确的方向。

谢谢

【问题讨论】:

  • 好问题。我认为这是任何使用 webapp 的RequestHandler.redirect() 的人在他们第一次开始使用它时都会遇到的问题。

标签: python google-app-engine web-applications


【解决方案1】:

我建议您根据调用者是否应该继续执行从some_function() 返回一个布尔值。示例:

def some_function(self):
    if data['user'].new_user and not self.request.path == '/main/new':
        self.redirect('/main/new')
        return True
    return False

class Dashboard(webapp.RequestHandler):
    def get(self):
        if some_function(self):
            return
        #Continue with normal code here
        self.response.out.write('Some output here')

如果some_function() 嵌套了几个级别,或者如果您可能有许多这样的函数,那么还有一个稍微复杂的替代方案可能会有所帮助。这个想法:引发一个异常,指示您希望停止处理,并使用webapp.RequestHandler 的子类,它简单地捕获并忽略此异常。下面是一个大概的思路:

class RedirectException(Exception):
    """Raise this from any method on a MyRequestHandler object to redirect immediately."""
    def __init__(self, uri, permanent=False):
        self.uri = uri
        self.permanent = permanent

class RedirectRequestHandler(webapp.RequestHandler):
    def handle_exception(self, exception, debug_mode):
        if isinstance(exception, RedirectException):
            self.redirect(exception.uri, exception.permanent)
        else:
            super(MyRequestHandler, self).handle_exception(exception, debug_mode)

这可能会使some_function() 的工作更容易一些(并使您的其他请求处理程序更易于阅读)。例如:

def some_function(self):
    if data['user'].new_user and not self.request.path == '/main/new':
        raise RedirectException('/main/new')

class Dashboard(RedirectRequestHandler):
     # rest of the implementation is the same ...

【讨论】:

  • 两个很棒的解决方案,第二个随着我的学习进度打开了我的思路。返回一个布尔值是我一直在做的,但你已经为我整理了一下 - 非常感谢你的回复。
  • 老实说,我只是在 10 分钟后才意识到异常引发,它开始变得更加清晰,但我认为它仍然在我脑海中。我会调查一下,不过非常感谢。
  • 布尔方法当然更简单,对于简单的情况(比如您在问题中提出的情况)就足够了。只需将异常方法放在你的后袋中,并在布尔方案变得更棘手时考虑它(例如,嵌套函数或大量函数,如 some_function())。
【解决方案2】:

这个怎么样?

class Dashboard(webapp.RequestHandler):
    def some_function(self):
        if data['user'].new_user and not self.request.path == '/main/new':
            self.redirect('/main/new')
            return True
        else:
            return False
    def get(self):
        if not self.some_function():
            self.response.out.write('Some output here')

作为参考,如果您需要在很多 RequestHandlers 中使用 some_function(),那么创建一个您的其他 RequestHandlers 可以从其子类化的类将是 Pythonic:

class BaseHandler(webapp.RequestHandler):
    def some_function(self):
        if data['user'].new_user and not self.request.path == '/main/new':
            self.redirect('/main/new')
            return False
        else:
            return True

class Dashboard(BaseHandler):
    def get(self):
        if not self.some_function():
            self.response.out.write('Some output here')

【讨论】:

  • 正如我在另一个答案中评论的那样,我一直在返回一个布尔值,但你让它对我来说更干净一些,而且通常让我的思路开阔了一点。我喜欢你关于设置一个 RequestHandlers 可以继承的类的想法,我会这样做 :) 感谢你为我指明了成为真正 Python 负责人的正确方向。我在 PHP 方面有 6 年的经验……只有几天的 Python 经验,要学习的东西太多了!
  • 我是 StackOverflow 的新手,这是标记为已接受的答案,因为我将同时使用布尔部分和关于如何更“pythonic”的第二个建议 :) 非常感谢两者不过你们。
【解决方案3】:

我知道这个问题已经很老了,但我今天正在做某事,自然而然地尝试了另一种解决方案而没有考虑它,它工作得很好,但我想知道这样做会不会有问题。

我现在的解决方案是返回,实际上返回任何东西,但我使用“return False”,因为请求存在问题,所以我打印错误或重定向到其他地方。

通过返回,我已经设置了输出等,我将提前终止 get() 或 post() 函数。

这是一个好的解决方案吗?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-31
    • 2020-11-15
    • 1970-01-01
    • 1970-01-01
    • 2013-03-27
    • 1970-01-01
    相关资源
    最近更新 更多