尴尬地问,但我正在使用webapp2,我正在试验一个解决方案,以便更容易定义路由based on this google webapp2 route function。但这一切都取决于能否在子级别定义TYPE_NAME
。想法是父母设置一切,孩子只需要实现_list
功能。我遇到的问题是TYPE_NAME
是无,我需要它成为孩子。
#main WSGI is extended to have this function
class WSGIApplication(webapp2.WSGIApplication):
def route(self, *args, **kwargs):
def wrapper(func):
self.router.add(webapp2.Route(handler=func, *args, **kwargs))
return func
return wrapper
from main import application
class ParentHandler(RequestHandler):
TYPE_NAME = None
@application.route('/', name="list_%s" %TYPE_NAME)
def list(self):
return self._list()
class ChildHandler(ParentHandler):
TYPE_NAME = 'child'
def _list(self):
return []
我尝试了一些使用“类属性”的解决方案,但它们没有成功。对其他想法开放,我基本上只需要子类继承装饰属性并执行它们。
修改
对于座位边缘的所有人都在想我如何解决这个问题,我无法从装饰器中获得所需的一切,所以我最终使用了一个meta。我还添加了_URLS
参数以允许添加其他“路由”。它将custom
函数映射到路径。真的很想使用装饰,但无法让它工作。
class RequestURLMeta(type):
def __new__(mcs, name, bases, dct):
result = super(RequestURLMeta, mcs).__new__(mcs, name, bases, dct)
urls = getattr(result, '_URLS', {}) or {}
for k,v in urls.iteritems():
template = v.pop('template')
app.route(getattr(result, k), template, **v)
if getattr(result, 'TYPE_NAME', None):
app.route(result.list, result.ROOT_PATH, methods=['GET'],name="%s" % result.TYPE_NAME)
#other ones went here..
return result
class ParentHandler(RequestHandler):
__metaclass__ = RequestURLMeta
class ChildHandler(ParentHandler):
TYPE_NAME = 'child'
_URLS = { 'custom': '/custom', 'TYPE_NAME': 'custom_test' }
def _list(self):
return []
def custom(self): pass
答案 0 :(得分:1)
我认为要让它工作,你将需要使用metaclass。它可能看起来像以下(未经测试):
from main import application
class RouteMeta(type):
def __new__(mcs, name, bases, dct):
type_name = dct.get("TYPE_NAME")
if type_name is not None:
@application.route('/', type_name)
def list(self):
return self._list()
dct["list"] = list
return super(RouteMeta, mcs).__new__(mcs, name, bases, dct)
class ParentHandler(RequestHandler):
__metaclass__ = RouteMeta
class ChildHandler(ParentHandler):
TYPE_NAME = 'child'
def _list(self):
return []
不是将list()
方法赋予ParentHandler
属性,而是为从ParentHandler
继承并定义TYPE_NAME
的类动态创建。{/ p>
如果RequestHandler
也使用自定义元类,则RouteMeta
继承RequestHandler.__metaclass__
而不是type
。
答案 1 :(得分:0)
此代码:
@application.route('/', name="list_%s" %TYPE_NAME)
def list(self):*emphasized text*
...
在语义上与此相同:
def list(self):
...
list = application.route('/', name="list_%s" %TYPE_NAME)(list)
即。方法route
在ParentHandler
范围内调用
无论你尝试什么懒惰的方法,它都行不通。你应该尝试一下
不同:
from main import application
def route_list(klass):
klass.list = application.route('/',
name="list_%s" % klass.TYPE_NAME)(klass.list)
return klass
class ParentHandler(RequestHandler):
def list(self):
return self._list()
class ChildHandler(ParentHandler):
TYPE_NAME = 'child'
def _list(self):
return []
# in python3 would be:
# @route_list
# class ChildHandler(ParentHandler):
# ...
ChildHandler = route_list(ChildHandler)