1

I'm new to Python and obviously I am finding it awesome.

Specifically, I'm building a small data API using Web.py and MIMERender.

I've organized it thusly: each table in the DB has a corresponding module with three classes.

# Define URL endpoints
urls = (

# Index
'/',                                'index',

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

)

Each of those classes are defined in a separate file. For example, the three disclosure classes are defined in disclosure.py: (note: this is very psuedo as the definitions are too involved and would distract from the main question)

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 }

At the top of each module, I define the lambda functions as per MIMERender and then in each of the class definitions I include the neccesary class decorator.

Problem is, I seem to be repeating myself. In each module, as in the example above, there are three classes to define and I have to put the very same class decorator in each one. Also, the same lamba function is included at the beginning of each module.

I could cut out a 17 or more LOC per module if I were more familiar with how Python deals with this sort of thing.

Is there any way I can make A) the module as a whole inherit the lambda function definitions, and B) each of the class methods inherit the class decorator?

Thanks in advance!

Alec Sloman
  • 699
  • 4
  • 18
  • You could make a class that encompasses the code that is copied over and over and just initialize it with special arguments. – Blender Mar 18 '12 at 23:21

1 Answers1

1

I think the easiest way to clean this up is to put your render functions and decorator into a separate module, e.g. foo.py, like this:

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,
)

Now your class file looks like this:

from foo import mimerender

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

The only trick here is that foo.py needs to be in your path or else you need to do a relative import, but those are entirely separate questions.

Community
  • 1
  • 1
Mark E. Haase
  • 25,965
  • 11
  • 66
  • 72