_renderers = {} def getrenderer(typ): for t in typ.__mro__: if t in _renderers: return _renderers[t] else: raise LookupError, "no renderer for %r"%(typ,) def setrenderer(typ, func): assert callable(func) _renderers[typ] = func def renderer(*typs): def _(func): for t in typs: setrenderer(t, func) return func return _ def render(ob): while not isinstance(ob, str): ob = getrenderer(type(ob))(ob) return ob @renderer(list, tuple) def renderSequence(ob): return ''.join(map(render, ob)) @renderer(str) def renderString(ob): return ob @renderer(int, long, float) def renderStr(ob): return str(ob) @renderer(unicode) def renderUnicode(ob): return ob.encode('utf-8') from nevow import tags as T @renderer(T.Tag) def renderTag(ob): return ob.children if __name__ == '__main__': print render(['a'])