Повторяющиеся декораторы классов в приложении Web.py / MIMERender - PullRequest
1 голос
/ 19 марта 2012

Я новичок в Python и, очевидно, нахожу это потрясающим.

В частности, я создаю небольшой API данных с использованием Web.py и MIMERender.

Я организовал это так: каждая таблица в БД имеет соответствующий модуль с тремя классами.

# Define URL endpoints
urls = (

# Index
'/',                                'index',

# Disclosures
'/disclosure/listAll',              'Disclosures',
'/disclosure/page/(.+)',            'DisclosurePage',
'/disclosure/(.+)',                 'Disclosure',

)

Каждый из этих классов определен в отдельном файле. Например, три класса раскрытия определены в disclosure.py: (примечание: это очень псевдо, так как определения слишком сложны и могут отвлечь от основного вопроса)

import web


# Define response formats
render_xml = lambda **args: dict2xml(args).display()
render_json = lambda **args: json.dumps(args)

class Disclosure:

@mimerender(
    default = 'json',
    xml  = render_xml,
    json = render_json,
)

def GET(self, primaryKey):

    ... ( retrieval and formatting ) ...
            return { 'response' : someResponse }

В верхней части каждого модуля я определяю лямбда-функции в соответствии с MIMERender, а затем в каждом из определений классов, которые я включаю в декоратор необходимого класса.

Проблема в том, что я, кажется, повторяюсь. В каждом модуле, как в примере выше, нужно определить три класса, и я должен поместить один и тот же декоратор классов в каждый. Кроме того, одна и та же функция lamba включена в начало каждого модуля.

Я мог бы сократить 17 или более LOC на модуль, если бы я был более знаком с тем, как Python справляется с подобными вещами.

Можно ли как-то сделать, чтобы А) модуль в целом наследовал определения лямбда-функции, и Б) каждый из методов класса наследовал декоратор класса?

Заранее спасибо!

1 Ответ

1 голос
/ 26 июня 2012

Я думаю, что самый простой способ убрать это - поместить ваши функции рендеринга и декоратор в отдельный модуль, например, foo.py, вот так:

from mimerender import FlaskMimeRender

def render_json(**view):
    """ do whatever """

def render_xml(**view):
    """ do whatever """

def render_html(**view):
    """ do whatever """

mimerender = FlaskMimeRender()(
    default = "html",
    html = render_html,
    xml = render_xml,
    json = render_json,
)

Теперь ваш файл класса выглядит следующим образом:

from foo import mimerender

class Disclosure:
    @mimerender
    def GET(self, primaryKey):
        """ do stuff """

Единственная хитрость здесь в том, что foo.py должен быть на вашем пути , иначе вам нужно сделать относительный импорт , но это полностьюотдельные вопросы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...