Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/359.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python包装器-关于变量范围的混淆_Python_Wrapper_Scope - Fatal编程技术网

Python包装器-关于变量范围的混淆

Python包装器-关于变量范围的混淆,python,wrapper,scope,Python,Wrapper,Scope,我认为我会很聪明,编写一个称为会话变量(很多存在)的包装器,并将其添加到需要会话变量的(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

我认为我会很聪明,编写一个称为会话变量(很多存在)的包装器,并将其添加到需要会话变量的(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”中无法访问用户_obj。我的理解是,这是一个内部函数,因此“wrapper”方法下列表中的变量可以被这个内部函数“main”访问。这里缺少什么?

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

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

@spam
def ham():
    pass
与语法完全相同

def ham():
    pass
ham = spam(ham)
这是否说明了为什么你所做的不起作用



如果要从装饰器向函数传递Stuff,通常的习惯用法是向函数发送额外的参数。这可能有点令人讨厌,因为这意味着看起来正确的argspec实际上不正确。

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

这种区别(也由解释器和运行时进行区分)在范围界定中绝对重要。看看s_vars包装器的dis(反汇编)(或相同行为的简化简单示例)。对于
func\u to\u
的不同值(此处仅为一个值),不会重新解释代码

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