运行相同的代码为get(self)作为post(self)

时间:2010-05-21 14:26:00

标签: python google-app-engine

在其他答案中已经提到过,对于任何给定的请求,def get(self)def post(self)都运行相同的代码。我想知道人们使用什么技术,我想:

class ListSubs(webapp.RequestHandler):
    def get(self):
        self._run()

    def post(self):
        self._run()

    def _run(self):
        self.response.out.write("This works nicely!")

4 个答案:

答案 0 :(得分:11)

我会建议理论和实际的原因,为什么你正在使用的方法(将公共代码重构为一个单独的方法并从post和get方法调用它)优于只有一个方法的明显更简单的替代方法这两种方法中的一种叫另一种方法。

从理论的角度来看,“方法A完全代表方法B”意味着“首要”或“不对称”的概念 - 一种设计决定,向前,任何可能适用于B的变化将不可避免地,本质上也适用于A; A可能在未来稍微定制B(在A调用B之前和/或之后添加一些额外的代码)但反之亦然。当没有理由期望这样的首要地位时,在代码中嵌入这个概念是一个糟糕的编码决定。通过让A和B都调用公共私有方法C,可以避免破坏对称性。

有些人对理论论点不满意,更喜欢实用论证:幸运的是,在这种情况下,理论直接转化为实用的。同样,这是代码未来演变的一个问题:同时使用A和B调用C会让您完全自由地进行小型自定义(在调用C之前和/或之后添加代码),或者两者都有,或者两者都没有A和B.因为你不知道你需要这种灵活性的哪些部分,而且简单性方面的成本微乎其微,采用简单灵活的路线是非常实用和可取的。

最后一个实用点(适用于任一选择):任何时候你都有这样的模式:

def amethod(self):
    return cmethod(self)

你通常(谦虚地)更好地重写这个

amethod = cmethod

这可以避免不必要的调用嵌套级别(平坦优于嵌套)。因此,您的课程可以有用地编码:

class ListSubs(webapp.RequestHandler):

    def _run(self):
        self.response.out.write("This works even better!")

    get = post = _run

没什么大不了的,如果您需要在嵌套调用之前或之后应用调整(从get_run,则必须重构为原始的“嵌套”方式等等)或者需要在调试中进行其他调整(例如,在post上的调试器中设置一个断点但没有get上的断点触发器等),但在可行的情况下进行简单的简化

答案 1 :(得分:2)

将完成工作的代码重构为自己的函数/方法是正确的方法。

答案 2 :(得分:2)

我用过这个:

class ListSubs(webapp.RequestHandler):
    def post(self):
        self.response.out.write("This works nicely!")
    def get(self):
        self.post()

答案 3 :(得分:1)

我在回答中没有看到的一件事,就是为什么你不应该这样做。在服务器上更改HTTP GET数据是个坏主意是一个相当普遍的原则。更改服务器的状态通常应该通过POST进行。因此,用于GETPOST的每个网址都应具有根据请求类型而有所不同的特定操作。 w3c也有一个很好的overview of when to use GET vs. POST

我倾向于将GETPOST视为吸气剂和制定者。 POST更改数据,GET获取数据。因此,简单搜索可以整天使用GET,但是当您将设置保存回服务器时,POST是有序的。

例如,假设您的博客中有帖子的网址(example.com/blog/post-vs-get/)。然后,您可以使用get()获取博客文章,并使用精美的评论表单将其呈现给屏幕。在此示例中,我的评论表单将POST返回到相同的URL,调用post()方法,该方法可以处理表单,然后返回相同的呈现页面。

class ListSubs(webapp.RequestHandler):
    def post(self):
        comment = cgi.escape(self.request.get('comment'))
        ## Do magic with our comment.
        self.get() ## Go off and return the rendered page.
    def get(self):
        ## Get the blog post out of the data store and render a page.
        self.response.out.write("""<html>
              <body>
                <p>My awesome blog post!</p>
                <form method="post">
                  <h1>Comment</h1>
                  <textarea name="comment" rows="3" cols="60"></textarea>
                  <input type="submit" value="Comment">
                </form>
              </body>
            </html>""")

这样可以在呈现页面和处理POST数据之间进行清晰的分工。这也可以防止您的代码在没有数据的请求上运行不必要的表单验证和/或处理。在我看来,这种职责分离也使调试和维护代码变得更容易。

相关问题