在python appengine中,如何从basehandler调用处理程序?

在python appengine中,如何从basehandler调用处理程序?,python,google-app-engine,web-applications,Python,Google App Engine,Web Applications,我想这样做: class Basehandler(webapp.RequestHandler): def __init__(self): if checkforspecialcase: #check something that always needs to be handled return SpecialCaseHandler.get() class NormalHandler(Basehandler): def get(self): print

我想这样做:

class Basehandler(webapp.RequestHandler):

  def __init__(self):
    if checkforspecialcase: #check something that always needs to be handled
      return SpecialCaseHandler.get()

class NormalHandler(Basehandler):

  def get(self):
    print 'hello world'
    return

class SpecialCaseHandler(Basehandler):

  def get(self):
    print 'hello special world'
    return
其思想是,无论最初调用什么处理程序,如果满足某个特定情况,我们基本上会切换到另一个处理程序


我对python非常陌生,所以我不确定我正在尝试做的事情是否可行。或者这是否是最好的方法。我真正想做的是,如果某人已经开始注册,但还没有完成,请确保向他们显示完整的个人资料页面。。。不管他们提出什么要求。因此,“checkforspecialcase”查看他们的会话并检查不完整的信息。

WSGIApplication根据URL路由传入请求。比如说,

application = webapp.WSGIApplication(
              [('/special-case', SpecialCaseHandler)])

checkforspecialcase
通过时,您可以使用
self.redirect(“/special case”)

WSGIApplication根据URL路由传入请求。比如说,

application = webapp.WSGIApplication(
              [('/special-case', SpecialCaseHandler)])

checkforspecialcase
通过时,您可以使用
self.redirect(“/special case”)
您的Basehandler只需实现一个get()来检查特殊情况,并重定向或调用self.view(),每个处理程序都可以实现view()(或您想调用它的任何东西),而不是get()

我并不是真的喜欢为我的每个处理程序编写一个类,或者非常明显地使用继承,所以我建议使用如下滚动装饰器:

routes = []

def get (route):
    def makeHandler (handle, *args, **kwargs):
        class Handler (webapp.RequestHandler):
            def get (self, *args, **kwargs):
                shouldRedirectToCompleteProfile = # do your test
                if shouldRedirectToCompleteProfile:
                    self.redirect('/special-case')
                else:
                    handle(self, *args, **kwargs)
        routes.append((route, Handler))
        return Handler
    return makeHandler

def post (route):
    def makeHandler (handle, *args, **kwargs):
        class Handler (webapp.RequestHandler):
            def post (self, *args, **kwargs):
                handle(self, *args, **kwargs)
        routes.append((route, Handler))
        return Handler
    return makeHandler

@get('/')
def home (ctx):
    # <...>

@get('/whatever/(.*)/(.*)')
def whatever (ctx, whatever0, whatever1):
    # <...>

@post('/submit')
def submit (ctx):
    # <...>

application = webapp.WSGIApplication(routes)
routes=[]
def get(路径):
def makeHandler(句柄、*args、**kwargs):
类处理程序(webapp.RequestHandler):
def get(自身、*args、**kwargs):
shouldRedirectToCompleteProfile=#进行测试
如果应重定向到完成配置文件:
self.redirect(“/特殊情况”)
其他:
手柄(自,*args,**kwargs)
routes.append((路由,处理程序))
返回处理器
返回makeHandler
def post(路线):
def makeHandler(句柄、*args、**kwargs):
类处理程序(webapp.RequestHandler):
def post(自我,*args,**kwargs):
手柄(自,*args,**kwargs)
routes.append((路由,处理程序))
返回处理器
返回makeHandler
@获取(“/”)
def home(ctx):
# 
@获取('/which/(.*)/(.*))
def任意值(ctx、任意值0、任意值1):
# 
@发布(“/submit”)
def提交(ctx):
# 
application=webapp.WSGIApplication(路由)

您的Basehandler可以只实现一个get(),该get()检查特殊情况并重定向或调用self.view(),每个处理程序都可以实现view()(或任何您想调用的)而不是get()

我并不是真的喜欢为我的每个处理程序编写一个类,或者非常明显地使用继承,所以我建议使用如下滚动装饰器:

routes = []

def get (route):
    def makeHandler (handle, *args, **kwargs):
        class Handler (webapp.RequestHandler):
            def get (self, *args, **kwargs):
                shouldRedirectToCompleteProfile = # do your test
                if shouldRedirectToCompleteProfile:
                    self.redirect('/special-case')
                else:
                    handle(self, *args, **kwargs)
        routes.append((route, Handler))
        return Handler
    return makeHandler

def post (route):
    def makeHandler (handle, *args, **kwargs):
        class Handler (webapp.RequestHandler):
            def post (self, *args, **kwargs):
                handle(self, *args, **kwargs)
        routes.append((route, Handler))
        return Handler
    return makeHandler

@get('/')
def home (ctx):
    # <...>

@get('/whatever/(.*)/(.*)')
def whatever (ctx, whatever0, whatever1):
    # <...>

@post('/submit')
def submit (ctx):
    # <...>

application = webapp.WSGIApplication(routes)
routes=[]
def get(路径):
def makeHandler(句柄、*args、**kwargs):
类处理程序(webapp.RequestHandler):
def get(自身、*args、**kwargs):
shouldRedirectToCompleteProfile=#进行测试
如果应重定向到完成配置文件:
self.redirect(“/特殊情况”)
其他:
手柄(自,*args,**kwargs)
routes.append((路由,处理程序))
返回处理器
返回makeHandler
def post(路线):
def makeHandler(句柄、*args、**kwargs):
类处理程序(webapp.RequestHandler):
def post(自我,*args,**kwargs):
手柄(自,*args,**kwargs)
routes.append((路由,处理程序))
返回处理器
返回makeHandler
@获取(“/”)
def home(ctx):
# 
@获取('/which/(.*)/(.*))
def任意值(ctx、任意值0、任意值1):
# 
@发布(“/submit”)
def提交(ctx):
# 
application=webapp.WSGIApplication(路由)

要保持物品干燥,请使用


要保持物品干燥,请使用


这是我尝试的第一件事,但没有成功。如果将self.redirect('/special case')放在上述条件之后,则会出现以下错误:“AttributeError:'NormalHandler'对象没有属性'request'”。只有在get()或post()方法中调用重定向,而不是从初始化方法调用重定向时,重定向才有效。是的,没错。为什么不在
get
方法中使用该条件呢?为什么我们需要一个
\uuuu init\uuuu
?因为我希望这个条件应用于所有页面,所以在basehandler类中执行一次是有意义的。我相信扩展basehandler的类中的get/post方法会覆盖basehandler中的get/post方法。因此,要将其放入get/post方法中,我需要将其放入每个get/post方法中。我只是想把衣服弄干。这是我第一次尝试,但没有成功。如果将self.redirect('/special case')放在上述条件之后,则会出现以下错误:“AttributeError:'NormalHandler'对象没有属性'request'”。只有在get()或post()方法中调用重定向,而不是从初始化方法调用重定向时,重定向才有效。是的,没错。为什么不在
get
方法中使用该条件呢?为什么我们需要一个
\uuuu init\uuuu
?因为我希望这个条件应用于所有页面,所以在basehandler类中执行一次是有意义的。我相信扩展basehandler的类中的get/post方法会覆盖basehandler中的get/post方法。因此,要将其放入get/post方法中,我需要将其放入每个get/post方法中。@bgporter的唯一问题是,如果在编写第100个处理程序时,意外地实现了get()而不是DoGet(),那么您将遇到一个恼人的错误。您可以编写一百个检查重定向的函数测试,或者编写一个查找get()重写的静态分析单元测试,从而让自己轻松起来。或者,如果你像我建议的那样使用decorator,你不需要任何测试,因为不可能引入这种bug