用装饰器定义多个类的python
我有基类:用装饰器定义多个类的python,python,python-2.7,metaprogramming,tornado,Python,Python 2.7,Metaprogramming,Tornado,我有基类: class BaseGameHandler(BaseRequestHandler): name = 'Base' def get(self): self.render(self.name + ".html") 现在,我需要定义它的几个子类,但问题是,它们必须有一个装饰器。等效代码为: @route('asteroid') class AsteroidGameHandler(BaseGameHandler): name = 'asteroid'
class BaseGameHandler(BaseRequestHandler):
name = 'Base'
def get(self):
self.render(self.name + ".html")
现在,我需要定义它的几个子类,但问题是,它们必须有一个装饰器。等效代码为:
@route('asteroid')
class AsteroidGameHandler(BaseGameHandler):
name = 'asteroid'
@route('blah')
class BlahGameHandler(BaseGameHandler):
name = 'blah'
也许还有一些。
这里有一点背景:这是一个tornado web应用程序,@route
装饰程序允许您将/blah
映射到BlahGameHandler
。此代码将/blah
映射到BlahGameHandler
和/asteroid
映射到AsteroidGameHandler
所以我认为我应该在python中使用元编程并动态定义所有这些类。我尝试了以下不起作用的方法(所谓不起作用,是指最终的web应用程序在/asteroid
和/blah
上都抛出404):
我错过了什么?这两个代码在运行时不是等价的吗 您使用的库仅查找模块中的全局类对象 将每个类设置为全局类;允许您以字典的形式访问模块命名空间:
for i in xrange(len(games)):
globals()[games[i][1].__name__] = route(games[i][0])(games[i][1])
include()
代码不会在列表中查找您的视图
具体而言,include()
使用以下循环来检测处理程序:
for member in dir(module):
member = getattr(module, member)
if isinstance(member, type) and issubclass(member, web.RequestHandler) and hasattr(member, 'routes'):
# ...
elif isinstance(member, type) and issubclass(member, web.RequestHandler) and hasattr(member, 'route_path'):
# ...
elif isinstance(member, type) and issubclass(member, web.RequestHandler) and hasattr(member, 'rest_route_path'):
# ...
dir(模块)
只考虑顶级对象。不工作不是问题描述。出了什么问题?您期望发生什么?您的代码看起来工作正常,只是没有在全局中设置对象。您遇到的问题到底是什么?那么,route()
从何而来?也许类装饰器有额外的要求,比如类是一个全局模块?这是@route
装饰器的来源还是其他什么?你真的调用了route.get_routes()
来列出某个点的路由吗?路由装饰器来自这里:
for member in dir(module):
member = getattr(module, member)
if isinstance(member, type) and issubclass(member, web.RequestHandler) and hasattr(member, 'routes'):
# ...
elif isinstance(member, type) and issubclass(member, web.RequestHandler) and hasattr(member, 'route_path'):
# ...
elif isinstance(member, type) and issubclass(member, web.RequestHandler) and hasattr(member, 'rest_route_path'):
# ...