Minoru
24.12.2011 17:48 antaeus
Есть у меня набор классов, каждый из которых я хотел бы хранить в отдельном файле, а последние складывать в отдельный каталог (чтобы не мешались). Но в таком случае их нельзя импортировать (каталог-то мой, в sys.path его нет). Можно превратить директорию в пакет, но тогда класс PageNotFound приходится импортировать монструозной конструкцией вида from pages.PageNotFound import PageNotFound.
Господа, как быть? Существует ли изящное решение, или мне модифицировать sys.path?
Использовать ocaml или haskell — изящное решение
В файл init.py пакета их пропиши, а путь к пакету добавь в sys.path
Ты имеешь в виду __all__ в __init__.py пакета? Это не то. Можно будет делать from pages import *, но доступ к классам все равно через имя класса будет (PageNotFound.PageNotFound, например).
Basically, я хочу что-то такое, чтобы классы были в отдельных файлах, строка импорта выглядела не так монструозно, а после импорта доступ к классу можно было осуществлять безо всяких модификаторов.
s/модификаторов/namespace specifiers/
Решил проблему, импортировав все модули пакета в его __init__.py:
from .PageNotFound import *
Теперь можно делать from pages import PageNotFound, всё работает.
В __init__.py в модуле-директории пишешь какой-нибудь импортер.
Да, именно его. Кто тебе мешает в init.py импортировать нужные тебе классы и вписать их в __all__?
А зачем в __all__ вписывать, коли уже импортировал?
Так и сделал, /5 же.
Хорошая практика. Хотя если ты импортировал только то, что тебе нужно, можно и опустить.
Погоди, разве __all__ не для того, чтобы указывать пакеты, которые следует импортировать при 'from PKGNAME import *'? Я думал, его только для этого и применяют.
Да, для этого. Я тут немного теряю нить обсуждения.
Если __all__ ни для чего кроме from PKG import * не используется, то мне всё ясно и обсуждение, вобщем-то, завершено. Если же эта переменная служит ещё какой-то цели, то я таки хотел бы узнать, какой — интереса ради.
> набор классов
> класс PageNotFound
> как быть?
> изящное решение
спасибо, сделал мой день!
Не понимаю, что именно тебе не понравилось. Помимо PageNotFound, в том же пакете сейчас ещё четыре класса, скоро прибавится ещё.
Да ничего-ничего, тебе всё равно не понять моей радости ибо #ohshin
Я таки требую объяснений.
-_-
Сам попробуй объяснить шутку человеку без чувства юмора — это скучно и безперспективно. Кому надо — тот сам давно посмотрел http://macton.smugmug.com/gallery/893670... например за оопмоска, ну а про питон и говорить особо нечего. В общем, сапиенти сат.
>галерея не работающая без яваскрипта >что-то говорит про хороший, неперегруженный код
а?
Ты меня обвиняешь в ООПГМ? Серьёзно?
Ок, вот тебе задача. На сайте есть странички. Также есть WSGI приложение, эти странички генерящее и раздающее. У каждой странички свой собственный html-шаблон и кусочек логики. Некоторые из страниц могут принимают не только GET, но и POST-запросы. Как ты это реализуешь? Просто накидай примерную структуру приложения.
А пока ты читаешь задание и набираешь ответ (на что я искренне надеюсь), я объясню, почему данную задачу я решил с помощью классов.
Основное приложение получает от сервера строку с запросом. Из неё легко извлекается адрес запрашиваемой страницы и переданные параметры. С точки зрения структурного программирования решением является большой switch, параметром которого является адрес странички, а в каждом case'е идёт проверка на то, каким именно методом передан запрос с последующим вызовом соответствующей функции. Ну или просто вызов функции, которая, опять-таки, проверяет тип запроса и вызывает другую функцию.
Мне это решение кажется излишне громоздким, поэтому я объявил список таплов (адрес, обработчик), где обработчик — это класс с методом __call__. Таким образом, главное приложение после получения запроса пробегается по списку (это медленнее, чем switch, но у меня будет не очень много разных страниц) и находит подходящий обработчик. Создаётся временный объект, который и вызывается с переданными GET'ом или POST'ом параметрами. В __call__ определяется тип запроса и вызывается self.get() или self.post(), где и происходит обработка данных и генерация странички результата.
Все классы-обработчики наследуются от базового класса, реализующего методы-заглушки.
Всё это позволяет мне добавлять страницы, не копипастя много кода (достаточно объявить новый класс, наследующийся от базового, и добавить его имя в список), что было бы неизбежно в случае структурного программирования (как минимум, пришлось бы копировать dispatcher, запускающий разные процедуры в зависимости от типа запроса).
На Python это пишется потому, что это курсовая работа по веб-технологиям, и единственной разрешённой альтернативой ему является PHP. Думаю, мой выбор теперь не вызывает удивления.
Извини за простыню, но ты меня реально задел.
Я не обвиняю, для меня это просто очевидно :) И вообще меня просто порадавало class TwoPlusTwo и т.п., просто посмеялся от души, хотя стоило бы поплакать, да...
А так спасибо, я говновебом не занимаюсь, его любой школьнег осилит.
> А пока ты читаешь задание и набираешь ответ (на что я искренне надеюсь)
Оставь недежду всяк сюда входящий (ц), я уж спал давно.
> я объясню, почему данную задачу я решил с помощью классов.
Мда, лучше б даже не начинал...
> просто вызов функции
> Мне это решение кажется излишне громоздким, поэтому я объявил список хуйни с трехуровневой иерархией.
...
> Все классы-обработчики наследуются от базового класса
Oh, I just saw it coming :)))
> это позволяет мне добавлять страницы, не копипастя много кода
Правильно, зачем мне писать много кода, пусть лучше компилятор нагенерит мне его ещё больше и тормознее! :)
> dispatcher
Ты поди и банду четырёх чтишь, да?
> потому, что это курсовая работа по веб-технологиям
> Думаю, мой выбор теперь не вызывает удивления.
Безусловно, я и сам на каком только говне курсовые не писал, это ещё хорошо что хоть питон у вас :)
> Извини за простыню, но ты меня реально задел.
А вот это реально хорошо (хотя цели я такой себе не ставил), значит ты не безнадёжен!
Где ты нашёл TwoPlusTwo?
> > просто вызов функции
> > Мне это решение кажется излишне громоздким, поэтому я объявил список хуйни с трехуровневой иерархией.
> ...
Похоже на тупую ненависть к ООП безо всякого обоснования. Монструозный switch мне кажется менее элегантным решением, чем список классов.
> > это позволяет мне добавлять страницы, не копипастя много кода
> Правильно, зачем мне писать много кода, пусть лучше компилятор нагенерит мне его ещё больше и тормознее! :)
За что ты так не любишь оптимизирующие компиляторы?
> > dispatcher
> Ты поди и банду четырёх чтишь, да?
Не читал и не собираюсь, вобщем-то.
для меня это выглядело как class TwoPlusTwo, если не class OnePlusOne :)
> тупую ненависть к ООП
Ненависть к ООП тупою не бывает!
> безо всякого обоснования
Сам гугли себе обоснавания, я уже одну ссылку давал, вот ещё: http://tinyurl.com/6kburz
> За что ты так не любишь оптимизирующие компиляторы?
За что ты так не любишь логику и подтасовываешь мои высказывания своими софизмами? Как сильно твои "оптимизирующие компиляторы" соптимизируют bubble sort? ;)
> > Ты поди и банду четырёх чтишь, да?
> Не читал и не собираюсь, вобщем-то.
А вот это правильно!
> Сам гугли себе обоснавания, я уже одну ссылку давал, вот ещё: http://tinyurl.com/6kburz
Я придерживаюсь той точки зрения, что ООП не так уж плохо, но его слишком часто используют даже там, где оно не нужно. Ты же, похоже, считаешь, что это просто гиблая парадигма.
> > За что ты так не любишь оптимизирующие компиляторы?
> За что ты так не любишь логику и подтасовываешь мои высказывания своими софизмами? Как сильно твои "оптимизирующие компиляторы" соптимизируют bubble sort? ;)
Я понимаю, что оверхед от диспатчинга методов никто мне не уберёт. Просто твоя фраза как бы намекнула, что оптимизировать нужно руками, что и привело к моему вопросу.
> Ты же, похоже, считаешь, что это просто гиблая парадигма.
Именно так, больше предпочитаю АОП/ДОП/ДДП.
> Просто твоя фраза как бы намекнула, что оптимизировать нужно руками, что и привело к моему вопросу.
Надо, в основном конечно алгоритмы (о чём я намекнул вопросом про bubble sort), но и в прямом смысле тоже порою надо — компилятор не всесилен и то что ты выкрутишь себе на всю -O3 -SSE3 -MakeItFast не гарантирует того, что он не пофакапит тебе выравнивание или ещё что-нибудь от чего всё будет тормозить — в общем рекомендую http://blog.gamedeff.com/?p=71 по этим вопросам почитать.
Закладки на эту серию валяются ещё с тех пор, как их на lwn постили, но все равно спасибо. Про АОП читаю, ДОП и ДДП не гуглятся что-то.
Странно, у меня отлично гуглятся: http://lmgtfy.com/?q=data%20oriented%20p... => {
http://gamesfromwithin.com/data-oriented...
http://www.gamedev.net/topic/575076-what...
http://stackoverflow.com/questions/41226...
}
http://en.wikipedia.org/wiki/Data-driven...
Ты дал русские аббревиатуры — я их и гуглил. Спасибо.
Тогда удивительно что ты даже аоп нагуглил :)
а как там в сравнении с питоном тем же?
а что там можно сравнивать?
решения
чего?