Skip to content

Commit

Permalink
edit
Browse files Browse the repository at this point in the history
  • Loading branch information
anonymous authored and anandology committed Jan 5, 2011
1 parent 98f43ee commit b9531ec
Showing 1 changed file with 49 additions and 1 deletion.
50 changes: 49 additions & 1 deletion MetaClassAutoURLS.md
Expand Up @@ -50,10 +50,21 @@ Of course, this is a simple example that leaves a lot to be desired (handling at

**AaronSw writes:** That's a clever idea. One improvement might be to have the classes inherit from a class with the metaclass set, so you don't have that unsightly `__metaclass__` every time.

**xunil writes:** Yeah, I went w/ this approach in the end since I found that I wanted each action class to inherit some common functionality anyway. You can [view the source](http://www.theanykey.com/svn/) for [my incomplete site](http://dev.theanykey.com) which uses a metaclass and decorators.

* * *

May be it's better to do it with decorators?

**xunil writes:** I originally tried to use decorators to do this since I was already familiar w/ them, but unless I'm missing something, decorators don't work on classes eg.

@action("/")
class Default:
def GET(self):
pass

That won't work. [The PEP for decorators](http://www.python.org/dev/peps/pep-0318/) describes it, but apparently it was never incorporated into the language (perhaps b/c metaclasses are available and do the same thing).

* * *

I couldn't figure out how to get this to work with URL classes in separate files, so I did something a little different, based on [this Python Cookbook recipe](http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/436873):
Expand Down Expand Up @@ -81,4 +92,41 @@ And then e.g. cgi_hello.py (in the same directory) would be:
def GET(self, name):
i = web.input(times=1)
if not name: name = 'world' for c in xrange(int(i.times)): print 'Hello,', name+'!'
Is this a terrible way to do it?
Is this a terrible way to do it?

* * *

**xunil writes:** This is not altogether a bad idea, but it again decouples the URL information from the class, making it a module-level tuple or list. You could combine your importing logic w/ my metaclass idea, actually, and achieve the same thing as me eg.

import os, web

for aaa in os.listdir(os.getcwd()):
module_name, ext = os.path.splitext(aaa)
if module_name.startswith('cgi_') and ext == '.py':
module = __import__(module_name)

if __name__ == "__main__":
import metaclass
web.run(metaclass.urls)

metaclass.py:

urls = [ ]

class ActionMetaClass(type):
def __init__(klass, name, bases, attrs):
urls.append(attrs["url"])
urls.append("%s.%s" % (klass.__module__, name))

cgi_hello.py:

import web
from metaclass import ActionMetaClass

class hello:
__metaclass__ = ActionMetaClass
url = '/(.*)'
def GET(self, name):
i = web.input(times=1)
if not name: name = 'world' for c in xrange(int(i.times)): print 'Hello,', name+'!'
* * *

0 comments on commit b9531ec

Please sign in to comment.