LINUX.ORG.RU

[python][велосипед] Надеюсь, я не Леннарт

 ,


0

2

Потихонечку перетаскиваю одно легаси приложение с Django 0.97. Встал вопрос о выборе фреймворка.

Любые с неявным контекстом в тредлокалах сразу идут лесом. То есть Flask, Bottle и иже с ними.

С жабой (или руби) головного мозга (использующие классы для организации контроллеров/вьюшек) идут туда же.

По сути, нужна красивая тончайшая обертка над мощными и гибкими библиотеками: WebOb (для создания собственно wsgi приложения), Beaker (сессии, кеш), Routes (диспатчинг) и wtforms (обработка и рендеринг хтмл форм). Я с ними по отдельности немножко знаком и они произвели хорошее впечатление своей документацией и архитектурой.

Ближе всех к этим требованиям стоит pyramid. Но меня смущает, что под слоем косметики (очень привлекательной, между прочим) находится жопа. И в нетривиальных случаях с ней придется разбираться. Все эти регистри и т.д., от этого несет таким унылым энтерпрайзом, что хочется плакать и звать маму.

Посоветуйте годных кандидатов, а то я уже свой начал пилить:

https://github.com/baverman/baito

Этакий явный фласк. Он уже рабочий и маленький кусочек, написанный на нем, уже отправился в продакшен. Остановите меня, пока не поздно.

★★★

Регистри в пирамиде это и есть неявный контекст в тредлокале, только энтерпрайзнее.

s_brin
()
Ответ на: комментарий от s_brin

Берёшь, например werkzeug

Мой велосипед был сначала оберткой для него. Печалит, что werkzeug вообще никаким боком не собирается переползать на py3. И сам автор какой-то неадекват, вспомнить хотя бы волшебную систему ленивой подгрузки модулей. Которую в последней версии убрал. o_O.

baverman ★★★
() автор топика
Ответ на: комментарий от s_brin

I am the Great Cornholio! Are you threatening me? I need TP for my bunghole!

baverman ★★★
() автор топика

«Нет, я не Леннарт, я другой» (с)

tailgunner ★★★★★
()

А чем, собственно, Django не угодил? В актуальной версии изменений в api минимум по сравнению с 0.97.

anonymous
()
Ответ на: комментарий от anonymous

А чем, собственно, Django не угодил?

Я из него использую только ORM и диспатчинг. Все остальное, начиная от авторизации и системы ролей, заканчивая шаблонизатором — сторонние или самописные библиотеки.

Основная проблема (сглупил по неопытности) модель приложения сильно завязана на ORM, с кучей кастомных query manager'ов, которые в первой джанге были полностью переписаны. Естественно, тестов тоже нет. Поэтому переползание на новую версию ничуть не легче полного рефакторинга модели.

Заодно преследуется цель по чистке кода, убирание дублей и написание тестов, в конце-концов. Джанга здесь, как собаке пятое колесо.

baverman ★★★
() автор топика

>Любые с неявным контекстом в тредлокалах сразу идут лесом.

Но почему? Если не заниматься извращениями, и понимать, как оно работает, эта штука только облегчает жизнь.

anonymous
()

(использующие классы для организации контроллеров/вьюшек)

Что не так? Мне лично очень понравилась эта фича в Django 1.3. Да и вообще Джанга нравится :)

power
()
Ответ на: комментарий от anonymous

Но почему?

Дурное эстетство. Мне нравится прекрасная концепция, что ендпойнт представляет из себя функцию, принимающую реквест и возвращающую респонз.

Тредлокалы нарушают эту симметрию. Ненавижу неявность.

baverman ★★★
() автор топика
Ответ на: комментарий от power

Что не так?

Ненужная со всех сторон сущность. Какую функциональную роль, помимо группировки логики (а просто по модулям разнести, что в сто крат лучше, во избежание километровых портянок?) она преследует?

Назови три юзкейза, когда нужны классы?

Еще стоит вопрос когда его инстанциировать. Если создание такого объекта на старте приложения хоть как-то оправдано — мы можем хранить там какой-то стейт, то в некоторых фреймворках он создается на каждый реквест, о_O.

baverman ★★★
() автор топика
Ответ на: комментарий от baverman

Так в чём проблема? Переползи на 1.3 и используй так-же только диспатчинг и псевдо-ORM. Убери в конфиге все миддлвари, админки и прочее. Не подключенные модули ресурсов не жрут.

У меня крутится на gunicorn_django, вcё очень быстро и стабильно, уже 125 дней аптайм одного приложения.

anonymous
()
Ответ на: комментарий от anonymous

Так в чём проблема?

Хочу заюзать sqlalchemy.

baverman ★★★
() автор топика
Ответ на: комментарий от baverman

Какую функциональную роль, помимо группировки логики (а просто по модулям разнести, что в сто крат лучше, во избежание километровых портянок?) она преследует?

Ну да, группировка логики. Классы типа типа HandbookPaginatedView или GetRelatedAjaxView значительно сокращают объем кода и его сложность. Я, конечно, не такой опытный разработчик и в ООП не силен, но преимущества class-based view мне сразу стали очевидны, как только прочитал о них в анонсе.

а просто по модулям разнести

Не понял о каких модулях идет речь.

power
()
Ответ на: комментарий от baverman

О питоновских модулях.

Ну а чем они лучше? И как ты ими собрался заменить классы в плане обобщения логики? Можешь юзкейсы привести? :)

power
()
Ответ на: комментарий от power

И как ты ими собрался заменить классы в плане обобщения логики? Можешь юзкейсы привести? :)

Зачем нужен инстанс класса, если нет состояния? Что заменять? Есть функции, принимающие запрос, отдающие ответ. Зачем класс? Я же говорю, иначе чем ООПГМ это не объяснить.

baverman ★★★
() автор топика
Ответ на: комментарий от baverman

Зачем нужен инстанс класса, если нет состояния?

Состояние есть в процессе. Оно, как раз, очень помогает для написания «универсальных» вьюсов.

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

def my_super_view(func1, func2, **kwargs):
    func1()
    # some common code
    func2()
    # another common code

А теперь представь, что пример сложнее. У меня так джанговский вьюс один раз дорос до 6-ти аргументов функций. Некрасиво и неудобно, имхо.

А в случае с классом ты просто переопределяешь нужное. По объёму кода примерно то же, но выглядит приличнее, чем def func(func1, func2, func3, func4). Плюс появляется возможность использовать mixin-ы, для разных content-type ответов, например.

Но это всё косметика, главное тут, как ты и написал, состояние:) В универсальной функции, что написана выше, func1 и func2 не могут передавать между собой данные. То есть если у тебя эти функции друг от друга зависят, то ты будешь всё переписывать заново. Или делать что-то общее, вроде

def my_super_view(func1, func2, **kwargs):
    result = func1()
    #skip
    result = func2(result)

В классах же оно всё тупо решается созданием атрибута класса, типа self.something в любом месте твоих func1 и func2. И код, при этом, понятен и прост. Без классов сложно написать что-то больше и крупное, имхо, но меру, конечно же, знать надо, чтобы не скатиться в ООПГМ.

Вот как-то так.

//другой анонимус.

anonymous
()
Ответ на: комментарий от baverman

> Зачем нужен инстанс класса, если нет состояния?

Я мало понимаю в вебе, но как у приложения может не быть состояния?

tailgunner ★★★★★
()
Ответ на: комментарий от anonymous

Например, есть у тебя функция, делающая три действия

Странные желания порождают странные проблемы, и, как следствие, странные пути решения.

baverman ★★★
() автор топика
Ответ на: комментарий от tailgunner

но как у приложения может не быть состояния?

В идеале, состояние веб приложения находится у клиентов (в браузерах). Вспомни cgi скрипты.

baverman ★★★
() автор топика
Ответ на: комментарий от baverman

>Странные желания порождают странные проблемы, и, как следствие, странные пути решения.

Как пример: писал сайтики на самодельной cms из джанги, делал прикрепляемые к страницам формы обратной связи с кастомными правилами отправки и прочего. Оказалось, что куча кода дублируется, но при этом другая куча кода остаётся. Использовались оба метода, и классы, и функции. Классы оказались лучше.

anonymous
()
Ответ на: комментарий от baverman

Я думал, что сейчас браузер хранит только cookie, а всё остальное серевр находит по этому cookie.

А cgi-скрипты я помню - неудобно было всё хранить в формах.

tailgunner ★★★★★
()
Ответ на: комментарий от anonymous

Классы оказались лучше.

Хорошо, поставим вопрос по другому, согласись, что если в фреймворке, ендпойнт это функция, то я смогу использовать класс, где это необходимо. То есть, ограничений никаких нет.

Но что делать если фреймворк *обязывает* использовать классы?

baverman ★★★
() автор топика
Ответ на: комментарий от baverman

>Хорошо, поставим вопрос по другому, согласись, что если в фреймворке, ендпойнт это функция, то я смогу использовать класс, где это необходимо. То есть, ограничений никаких нет.

Да, тут ты полностью прав.

В джанге и фласке так и сделано, собственно.

Но что делать если фреймворк *обязывает* использовать классы?

Наверное в питоне можно что-то намудрить с созданием класса на лету:) Но да, это криво и неудобно.

anonymous
()
Ответ на: комментарий от tailgunner

Я думал, что сейчас браузер хранит только cookie, а всё остальное серевр находит по этому cookie.

Ну это скорее практическое ограничение, вызванное лимитом на размер кук, да и тупо оверхедом на постоянное гоняние сессии, туда-сюда.

неудобно было всё хранить в формах.

Разработчики ASP(.NET) с тобой не согласятся.

baverman ★★★
() автор топика
Ответ на: комментарий от baverman

> Ну это скорее практическое ограничение, вызванное лимитом на размер кук, да и тупо оверхедом на постоянное гоняние сессии, туда-сюда.

Далеко не все данные о внутреннем состоянии должны быть доступны клиенту. Так что не только причиной является размер кук.

anonymous
()
Ответ на: комментарий от anonymous

Хранение сессии у клиента не означает, что он сможет ее прочитать.

baverman ★★★
() автор топика
Ответ на: комментарий от baverman

Ну вот в яве нет функций, есть только классы и интерфейсы. При этом на создание экземпляра класса без состояния (без полей) уходит времени не больше, чем на вызов функции в питоне.

note173 ★★★★★
()
Ответ на: комментарий от note173

Ну вот в яве нет функций, есть только классы и интерфейсы.

Речь идет про питон, в котором нет такого глупого ограничения.

baverman ★★★
() автор топика
Ответ на: комментарий от baverman

Ну а уж в питоне методы от свободных функций принципиально вообще не отличаются, какая разница, как структурировать код?

note173 ★★★★★
()
Ответ на: комментарий от note173

какая разница, как структурировать код?

Если фреймворк требует функции, то вообще без разницы. Но есть упоротые, class-only.

baverman ★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.