在我的金字塔代码中,我为不同的路径和模板多次注册一个函数。所以我的应用程序以不同的格式/视图显示相同的数据:
class MyViews(object):
@view_config(route_name='A', renderer='A')
@view_config(route_name='B', renderer='B')
@view_config(route_name='C', renderer='C')
@view_config(route_name='D', renderer='D')
def my_view(self):
return results
这很好用,但因为我有很多这种情况遵循某种模式,我想简化我的代码:
def entity_search_method(type_name):
def decorator(fkt):
fkt = view_config(route_name = A % type_name, ...)(fkt)
fkt = view_config(route_name = B % type_name, ...)(fkt)
fkt = view_config(route_name = C % type_name, ...)(fkt)
fkt = view_config(route_name = D % type_name, ...)(fkt)
return fkt
return decorator
然后:
class MyViews(object):
@entity_search_method('some_type')
def my_view(self):
return results
根据我的理解,这应该与直接调用装饰器完全相同。我甚至不需要关心functools.wrap
或类似的东西,因为我自己甚至都没有生成新的功能。但金字塔忽略了这种方法。什么暗示我可能会缺少什么?
答案 0 :(得分:2)
view_config
和拾取这些装饰器venusian
的底层库有点棘手。我想你在这里缺少的是你需要指定一个view_config(..., _depth=1)
来向venusian表明装饰者已被包裹。深度是指示您正在装饰的实际功能(在堆栈帧中)相对于view_config
装饰器的使用情况的位置。
答案 1 :(得分:0)
你没有申请装饰者;调用`view_config()的返回值,传入要装饰的项:
def entity_search_method(type_name):
def decorator(fkt):
fkt = view_config(route_name = A % type_name, ...)(fkt)
fkt = view_config(route_name = B % type_name, ...)(fkt)
fkt = view_config(route_name = C % type_name, ...)(fkt)
fkt = view_config(route_name = D % type_name, ...)(fkt)
return fkt
return decorator
@view_config(route_name='D', renderer='D')
语法获取表达式的返回值,并使用源代码中定义的下一个对象(另一个装饰器的函数或输出)调用它,返回值替换object-to-decorate
换句话说,以下内容:
@some_expression
def some_function():
pass
变为:
def some_function():
pass
some_function = some_expression(some_function)
但是Pyramid视图装饰器本身就是可以返回装饰器功能的callable。