Minoru
24.12.2011 17:48 antaeus
Есть у меня набор классов, каждый из которых я хотел бы хранить в отдельном файле, а последние складывать в отдельный каталог (чтобы не мешались). Но в таком случае их нельзя импортировать (каталог-то мой, в sys.path его нет). Можно превратить директорию в пакет, но тогда класс PageNotFound приходится импортировать монструозной конструкцией вида from pages.PageNotFound import PageNotFound.
Господа, как быть? Существует ли изящное решение, или мне модифицировать sys.path?

38 comments
recommend
bookmark
subscribe
Использовать 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...
Ты дал русские аббревиатуры — я их и гуглил. Спасибо.
Тогда удивительно что ты даже аоп нагуглил :)
а как там в сравнении с питоном тем же?
а что там можно сравнивать?
решения
чего?