Каковы некоторые рекомендации по структурированию приложений cherrypy?
Я пишу приложение cherrypy, и мне было интересно, как лучше всего структурировать мои обработчики и код для больших приложений?
Я понимаю, что назначение - это просто через cherrypy.root, но каковы методы написания обработчиков и их назначения?
(Позвольте мне доказать свою путаницу!) Сначала я хотел написать стандартный класс-обработчик, который выводит шаблон для запуска на основе текущего URL-адреса или комбинации класса / метода. Затем я бы назначил один экземпляр этого обработчика несколько раз пути для создания страниц. Однако я не вижу, как это работает, поскольку рекурсивные ссылки не будут работать правильно.
Так что, учитывая тот факт, что я уже рисую пробелы в том, как должен выглядеть мой собственный исходный код, я бы хотел получить несколько указателей и примеров!
Не стесняйтесь задавать некоторые подробные вопросы для меня, чтобы уточнить. В то время как есть много учебного материала из вишневого дерева, он имеет тенденцию только царапать поверхность.
2 ответа
CherryPy намеренно не требует от вас создавать подклассы из базового класса, предоставляемого фреймворком, чтобы вы могли свободно разрабатывать свой собственный механизм наследования или, что более важно, вообще не использовать его. Вы, безусловно, можете определять свой собственный базовый класс и наследовать его; таким образом, вы можете стандартизировать конструкцию и конфигурацию обработчика через __init__
метод вашего класса, а также через переменные и методы уровня класса.
Тем не менее, предпочтительный подход отличается. Для большинства веб-приложений вы на самом деле не хотите изменять фактическую логику построения ваших обработчиков, а также не заботитесь о переменных или методах уровня класса; вместо этого вы хотите использовать переменные и методы многократного использования для каждого URI или для поддерева URI или для сайта, а не для класса. Вы склонны отличать один набор обработчиков от другого набора более в зависимости от конфигурации экземпляра (метаданные обработчика) и методов экземпляра (логика обработчика). Традиционное наследование на основе классов может сделать это, но это немного тупой инструмент для такой настройки.
Таким образом, CherryPy разработан для обеспечения такого рода настройки набора ресурсов, что наследование на основе классов не дает должного результата. Это обеспечивается посредством 1) разработки системы конфигурации, которая позволяет привязывать метаданные к одному URI, поддереву URI, поддереву обработчиков или целому сайту с одинаковым синтаксисом (см. http://docs.cherrypy.org/dev/intro/concepts/config.html для обзора) и 2) система хуков и инструментов, которая позволяет привязывать логику к одному URI, поддереву URI, поддереву обработчиков или весь сайт. См. http://docs.cherrypy.org/dev/intro/concepts/tools.html
Итак, практически: используйте нормальные атрибуты на cherrypy.root
построить ваше дерево обработчиков:
def make_app():
root = Root()
root.foo = Foo()
root.bars = BarCollection()
return root
Однако не делайте Root, Foo и Bar наследуемыми от общего базового класса. Вместо этого, пишите независимые Инструменты, чтобы делать такие вещи, как "выводить шаблоны". То есть вместо:
from cherrypy import expose
class Foo(MyAppBase):
@expose()
def index(self, a, b, c):
...
root.foo = Foo(template='foo.html')
записывать:
from cherrypy import expose, tools
class Foo(object):
@tools.render(template='foo.html')
@expose()
def index(self, a, b, c):
...
root.foo = Foo()
... где 'tools.render' - инструмент CherryPy, который вы написали для поиска и применения данного шаблона. Этот подход позволит вам переопределить аргументы инструмента в вашем конфигурационном файле и избежать переупаковки или исправления вашего кода:
[/foo/]
tools.render.template = 'foo2.html'
Это очень субъективный вопрос, но я попробую.
Прежде всего, всегда храните базу данных и код данных отдельно от веб-кода. У меня есть много небольших файлов с одним классом каждый в
DB/
папки, которые все объединены вBase.py
файл, например:Интернет / Base.py - основной "базовый" класс, который включает классы из других веб-файлы, запускает веб-сервер в
Не забывайте__init__
Users.py - класс, который включает методы в основном из "DB/Users.py" который проверяет разрешения и т. д. перед возвратом (вы можете хотите добавить безопасность на уровне БД позже)... DB / Base.py - основной базовый класс БД, включая другие классы БД. Создает новые экземпляры SQLAlchemy/ любые и создать схемы базы данных, если они этого не делают и т. д. Может быть платным за использование методов для всей базы данных здесь, чтобы создавать связи и т. д. в одном месте, если вы решите изменить базы данных позже Users.py - файл класса хранилища БД пользователя / пароля и т.д.... Шаблоны / (HTML-шаблоны находятся здесь) Статический / (Статические изображения /CSS/javscript и т. Д. Находятся здесь)__init__.py
в каждом каталоге модулей, конечно, поэтому python может найти модули в подкаталогахНа мой взгляд, не всегда имеет значение, какие методы вы используете для структурирования кода, но будьте последовательны. Я пишу документ со всеми моими соглашениями с моими обоснованиями их использования и стараюсь следовать им до той точки, в которой это имеет смысл, но как всегда
a foolish consistency is the hobgoblin of small minds
, как цитируют документы в стиле Python:-)- Старайтесь использовать классы, а не прямые функции. Это может не иметь значения для небольших проектов, но для любых нетривиальных вещей могут возникнуть трудности. Я предпочитаю иметь много файлов с определенной целью и только один класс в одном файле, кроме тех случаев, когда имеет смысл иметь несколько
- Это один, вероятно, спорно - я обычно называют мои занятия
Class
и просто укажите его по имени модуля. Приведу пример Base.py:
Это помогает уменьшить проблемы, когда другие модули ссылаются друг на друга при импорте, посколькуimport Users class Base(Users.Class): def
__init__
(self): Users.Class.__init__
(self)from Users import Users
будет конфликтовать, еслиUsers.py
имеетfrom Base import x
поэтому я всегда ссылаюсь на имя модуля. Это просто личное предпочтение, так что делайте, что хотите:-P
Надеюсь, вы уловили идею из этого поста.