Question

If a pre-compiled property is a property that is calculated and cached on the first access; I'd like to do the same but, instead, take multiple lists and compile them to one master list.

For a little background, I'm currently building a site GAE/python/webapp2/jinja2. Sparing the nitty-gritty, my list of routes is growing pretty large. Currently, I have static routes, dynamic routes, and redirects all mashed up into one list.

Example:

master = [
  Route('/',StaticHandler, defaults={'_uri':'index.html'}),
  Route('/about-us', StaticHandler, defaults={'_uri':'index.html'})
  Route('/secure/', AuthHandler, defaults={'_uri':'secure.html'}),
  Route('/secure/<_uri>', AuthHandler, defaults={'_uri':'not-found.html'})
  Route('/about.html', RedirectHandler, defaults={'_uri':'about-us'})]

To keep things simple, I'd like to group them like:

main = [
  Route('/',StaticHandler, defaults={'_uri':'index.html'}),
  Route('/about-us', StaticHandler, defaults={'_uri':'index.html'})]

auth = [
  Route('/secure/', AuthHandler, defaults={'_uri':'secure.html'}),
  Route('/secure/<_uri>', AuthHandler, defaults={'_uri':'not-found.html'})]

redirect = [
  Route('/about.html', RedirectHandler, defaults={'_uri':'about-us'})]

Currently I'm using:

master = main + auth + redirects

Which works but I'm thinking that I need to wrap this in a class property to make it cacheable.

So far, I have tried:

class master(object):
  def __init__(self):
    self.list = list(set(main) & set(auth) & set(redirects))
  def __iter__(self):
    return iter(self.list)

But I get the error, "TypeError: 'type' object is not iterable".

So I need 2 things:

  1. A way to wrap the combined list as a class property
  2. A way to make the property cacheable (preferrably as a decorator)

What I don't want to deal with is the added overhead incurred by doing a list compilation on every call.

I have read about and used a cached property decorator but I'm not really clear on how they work and/or if they could be easily adapted to work with lists.

Note: Although contrived, the example here is meant to keep things simple. The long term goal here is be to provide 2 different sets of routes depending on the app configuration.

Was it helpful?

Solution

Your starting presumption, that the routes list is calculated on every request, is wrong. These are defined at the module level, so will be calculated the first time they are imported which is when each instance starts up. Pre-compiling or memoizing would just do exactly the same.

OTHER TIPS

I apologize if I misunderstand you, but.. would this basically do what you want? ..

a = [1,2,3]
b = [4,5,6]
c = [7,8,9]

class master(object):
    routes = a+b+c

if __name__ == '__main__':
    m = master()
    print m.routes

Yields:

[1, 2, 3, 4, 5, 6, 7, 8, 9]

But, more importantly..

a = master()
b = master()

b.routes.append(100)

print b.routes
# [1, 2, 3, 4, 5, 6, 7, 8, 9, 100]

print a.routes
# [1, 2, 3, 4, 5, 6, 7, 8, 9, 100]
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top