Выполнение того же кода для добирается (сам) как сообщение (сам)

Его, упомянутый в других ответах о получении того же кода, работающего за обоими 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!")
5
задан Peter Farmer 21 May 2010 в 14:26
поделиться

4 ответа

Я бы предложил как теоретические, так и практические причины того, почему используемый вами подход (рефакторинг общего кода в отдельный метод и вызов его из методов 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 to _run и т. д.) или нужны другие настройки в отладке (например, установите точку останова в отладчике на post , но без триггера точки останова на get и т. Д.), Но небольшое приятное упрощение для тех случаев, когда это возможно.

11
ответ дан 18 December 2019 в 10:42
поделиться

Рефакторинг кода, выполняющего работу, в его собственную функцию / метод - правильный метод.

2
ответ дан 18 December 2019 в 10:42
поделиться

Я использовал это:

class ListSubs(webapp.RequestHandler):
    def post(self):
        self.response.out.write("This works nicely!")
    def get(self):
        self.post()
2
ответ дан 18 December 2019 в 10:42
поделиться

Одна вещь, которую я не увидел в ответах и ​​которые я добавлю, - это то, почему вам не следует этого делать. Довольно распространенный принцип, что изменение данных на сервере HTTP GET - плохая идея. Изменение состояния сервера обычно должно происходить с помощью POST . В результате каждый URL-адрес, который используется как для GET , так и для POST , должен иметь определенные действия, которые различаются в зависимости от типа запроса. В w3c есть хороший обзор того, когда использовать GET по сравнению с POST .

Я склонен думать о GET и POST как о геттере и сеттере. POST изменяет данные, а GET получает данные. В результате простой поиск может использовать GET в течение всего дня, но когда вы сохраняете настройку обратно на сервер, POST в порядке.

Например, у вас есть URL-адрес сообщения в вашем блоге ( 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. Это также предохраняет ваш код от ненужной проверки формы и / или обработки запроса без данных. На мой взгляд, такое разделение обязанностей также упрощает отладку и сопровождение кода.

1
ответ дан 18 December 2019 в 10:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: