0

在我的 Pyramid 代码中,我为不同的路线和模板多次注册了一个函数。所以我的应用程序以不同的格式/视图显示相同的数据:

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或类似的事情,因为我自己什至不生成新函数。但是 Pyramid 忽略了这个方法。任何提示我可能会错过什么?

4

2 回答 2

2

view_config拾取这些装饰器的底层库venusian有些棘手。我认为您在这里缺少的是您需要指定 aview_config(..., _depth=1)以向 venusian 表明装饰器已被包装。深度是您正在装饰的实际功能(在堆栈帧中)相对于view_config装饰器使用情况的指标。

于 2013-09-12T18:50:39.920 回答
0

你没有应用装饰器;调用`view_config()的返回值,传入要装饰的item:

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')语法获取表达式的返回值,并使用源中定义的下一个对象(另一个装饰器的函数或输出)调用它,返回值替换对象到装饰。

换句话说,如下:

@some_expression
def some_function():
    pass

变成:

def some_function():
    pass
some_function = some_expression(some_function)

但是 Pyramid 视图装饰器本身就是返回装饰器函数的可调用对象。

于 2013-09-12T08:31:45.613 回答