Такой стиль характерен для CLI, функция render() — для GUI. Поскольку web-приложение это однозначно GUI, то там однозначно стоит использовать render().
Что касается континуаций. Я слегка сократил код, использовав lambda-функции для заполнения полей Test1.name и Test1.text. При наступлении события вызываются методы action() для всех полей формы, выполняются лямбды, которые сохраняют данные в переменных, после чего вызывается action() для submit-а и данные кладутся в базу. По сути, да, тут континуации не нужны. Но с тем же успехом я мог бы класть данные не в базу а дописывать их в массив. Правда, тогда сообщения были бы видны только добавившему их пользователю, что для гостевой книги несколько странно :)
Вот как следовало бы написать код в этом случае:
class Test1(object):
def __init__(self):
self.name=var.Var("")
self.text=var.Var("")
self.messages=[]
def add_rec(self):
self.messages.append([self.name,self.text])
@presentation.render_for(Test1)
def render(self, h, *args):
...............................................
# Вывод ранее введенных сообщений:
with h.table:
for r in self.messages:
with h.tr:
with h.td(valign="top", align="right"):
h<<h.b(r[0])<<":"
with h.td:
h<<r[1]
.................................................
html там не главное, я применил этот метод просто для упрощения примера. Это всего лишь одна из побочных, но красивых фич, как и трансляция питона в javascript, например, которая там также присутствует. Если ее оторвать, фреймворк потеряет немного, но эта вещь из тех, что лучше иметь, чем не иметь.
а зачем в данном конкретном примере шаблон? И css? with-конструкции дают возможность писать простой и очень читабельный, чистый код. Никто не призывает верстать с их помощью мегапорталы, хоть это и возможно :)
это не шаблоны :) Шаблоны там тоже есть, но смысл из примененять в простой программе? Конструкции с with — просто очень красивый способ автоматического закрытия тэгов. Кстати, при использовании шаблонов ничто не мешает вставлять в них куски кода, сгенерированного таким образом, что позволяет, иногда, сильно упростить сами шаблоны.
да практически в любом приложении с нетривиальной логикой или таком, где нужно работать с большим количеством вводимых пользователем данных. Например, вместо того, чтобы делать одну огромную форму, можно очень легко сделать «визард» с кнопками «вперед» и «назад», практически ничего не меняя, поскольку значения с предыдущих шагов будут спокойно лежать в переменных.
— так задается функция, аналогичная функции перерисовки в десктопных приложениях. Все глобальные переменные и методы объекта Test1 сохраняются при перезагрузках, можно хранить в них, например, статус авторизованности пользователя. Глобальные переменные еще и общие для всех потоков.
основная возможность stackless, используемая в Nagare — это сохранение continuations между запросами, так что приложение можно писать «линейно», аналогично десктопному. Но и взаимодействие между потоками можно устроить. Например, при помощи глобальных переменных :)
прочитал. Автор какие-то тривиальные вещи излагает, если откровенно. Серебряной пули, конечно, не существует и необходимость наличия мозгов еще никто не отменял. До сих пор еще не создан язык программирования, которым можно было бы пользоваться, совсем не применяя мозг. Разве что, PHP :)
Да, я сразу подумал, что на лисп это должно ложиться очень хорошо. Но я не настолько крут, чтобы писать приложения целиком на лиспе. Т.е. я могу, но код получается write-only :)
Что касается континуаций. Я слегка сократил код, использовав lambda-функции для заполнения полей Test1.name и Test1.text. При наступлении события вызываются методы action() для всех полей формы, выполняются лямбды, которые сохраняют данные в переменных, после чего вызывается action() для submit-а и данные кладутся в базу. По сути, да, тут континуации не нужны. Но с тем же успехом я мог бы класть данные не в базу а дописывать их в массив. Правда, тогда сообщения были бы видны только добавившему их пользователю, что для гостевой книги несколько странно :)
Вот как следовало бы написать код в этом случае:
В приведенном примере
@presentation.render_for(Test1)
def render(self, h, *args):
— так задается функция, аналогичная функции перерисовки в десктопных приложениях. Все глобальные переменные и методы объекта Test1 сохраняются при перезагрузках, можно хранить в них, например, статус авторизованности пользователя. Глобальные переменные еще и общие для всех потоков.
:)