【问题标题】:Custom decorator for Pyramid views: View function is ignored?金字塔视图的自定义装饰器:视图功能被忽略?
【发布时间】:2013-09-12 08:17:32
【问题描述】:

在我的 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 忽略了这个方法。任何提示我可能会丢失什么?

【问题讨论】:

    标签: python decorator pyramid python-decorators


    【解决方案1】:

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

    【讨论】:

    【解决方案2】:

    你没有应用装饰器;调用`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 视图装饰器本身是可调用的,可返回装饰器函数。

    【讨论】:

    • 抱歉,我更新了我的问题。你是对的,但这正是我在我的代码中所做的。我只是在复制和减少代码时犯了一个错误。我应用了装饰器,但该方法仍然被忽略。
    • 如果您在此装饰器之上手动应用相同的装饰器会发生什么?那么将它们放在@entity_search_method('some_type') 行之前?
    • 它工作正常。如果我将自己的放在其他人之上,它也可以工作。
    • 您使用的 view_config() 参数是否与自定义装饰器生成的完全相同?此代码中没有任何内容表示未应用装饰器。
    • 在我原来的装饰器中,我当然使用type_name 来生成参数。出于测试目的,我硬编码了与手动解决方案完全相同的值。它仍然不起作用。据我了解,我的代码应该与手动应用装饰器完全相同。所以必须发生一些非常奇怪/愚蠢的事情。但我不明白!?
    猜你喜欢
    • 2017-07-03
    • 2017-04-05
    • 2014-06-07
    • 1970-01-01
    • 2012-11-18
    • 1970-01-01
    • 1970-01-01
    • 2016-04-15
    • 1970-01-01
    相关资源
    最近更新 更多