0

我想我会很聪明,写一个调用会话变量的包装器(很多都存在)并将其添加到需要会话变量的(django)视图中。但是我似乎不理解变量的范围,或者我写错了。

我的包装是:

def s_vars(func_to_decorate):
    @wraps(func_to_decorate)
    def wrapper(request, *args, **kwargs):
        #add all the session variables to kwargs and accessible for the decorated function.
        user_obj = request.user
        datepicker = request.session['datepicker']
        date_format = request.session['date_format']
        .........
        country = request.session['country']
        metric = request.session['metric']
        qrydtm = request.session.get("qrydtm",date.today())

        result = func_to_decorate(request, *args, **kwargs)

        #any post view checks to be done go here

        #return to the function to be decorated.
        return result
    return wrapper

然后对于视图,我有类似的东西:

@s_vars
def main(request, template_name='placeholder.html'):
    return render_to_response(template_name, RequestContext(request,{
           'user':user_obj
            }))

但这会导致在方法“main”中无法访问 user_obj 的错误。我的理解是这是一个内部函数,因此这个内部函数“main”可以访问“包装器”方法下列表中的变量。我在这里想念什么?

4

3 回答 3

2

语法

@spam
def ham():
    pass

正好等价于语法

def ham():
    pass
ham = spam(ham)

这是否阐明了为什么您正在做的事情不起作用?


如果你想从装饰器向函数传递东西,通常的习惯是向函数发送额外的参数。这可能有点恶心,因为这意味着看起来正确的 argspec 实际上不是。

于 2012-12-28T16:47:29.387 回答
0

嵌套函数仅从定义它们的作用域中获取作用域变量,并且绑定发生在编译时。

以后不能添加作用域变量,当然也不能使用简单的包装器。

于 2012-12-28T16:47:24.347 回答
0

在调用内部函数的地方它只是由外部作用域函数调用,而不是在其中定义

这种区别(也由解释器与运行时做出)在范围界定中绝对重要。看一下 s_vars 包装器的 dis(反汇编)(或相同行为的简化示例)。代码不会针对func_to_decorate.

如果您想为内部函数提供可用的变量列表,那么传入的对象可能更有意义。包装器可以确保外部 API 没有它。

于 2012-12-28T16:47:41.217 回答