Skip to content

Instantly share code, notes, and snippets.

@GrahamDumpleton
Last active August 29, 2015 13:59
Show Gist options
  • Save GrahamDumpleton/10609688 to your computer and use it in GitHub Desktop.
Save GrahamDumpleton/10609688 to your computer and use it in GitHub Desktop.
Delay decorator action until class instantiation to allow access to class variable.
class Router(object):
def __init__(self):
self.methods = {}
def route(self, url):
def decorator(wrapped):
wrapped.__route_info__ = (self, url)
return wrapped
return decorator
def register(self, url, method):
self.methods[url] = method
def dispatch(self, url):
return self.methods[url]()
router = Router()
class ApplicationMetaClass(type):
def __new__(cls, name, bases, attrs):
instance = super(ApplicationMetaClass, cls).__new__(cls, name, bases, attrs)
for attrname, attrvalue in attrs.iteritems():
info = getattr(attrvalue, '__route_info__', None)
if info is not None:
mount_point = attrs.get('__mount_point__', ApplicationRoot.__mount_point__)
info[0].register(mount_point+info[1], attrvalue.__get__(instance, cls))
return instance
class ApplicationRoot(object):
__metaclass__ = ApplicationMetaClass
__mount_point__ = ''
class Application1(ApplicationRoot):
@router.route('/')
def root(self):
return self.__mount_point__, 'root'
@router.route('/suburl')
def suburl(self):
return self.__mount_point__, 'suburl'
class Application2(ApplicationRoot):
__mount_point__ = '/app1'
@router.route('/')
def root(self):
return self.__mount_point__, 'root'
@router.route('/suburl')
def suburl(self):
return self.__mount_point__, 'suburl'
app1 = Application1()
app2 = Application2()
print router.methods
print
print router.dispatch('/')
print
print router.dispatch('/suburl')
print
print router.dispatch('/app1/')
print
print router.dispatch('/app1/suburl')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment