函数参数,其值既不是由调用者传入也不是默认值

时间:2011-11-29 20:50:00

标签: python django

我有一个像这样的装饰者:

def region_required(view_func):
    def new_view(request, ctx = {}, *args, **kw):
        import pdb; pdb.set_trace()
        ctx['regions'] = Region.objects.all()
        return view_func(request, context=ctx, *args, **kw)
    return new_view

我用它来装饰视图函数。

今天我注意到一些非常奇怪的事情,ctx(context)参数有时会包含属于最后一个HTTP请求的数据。然后我把它缩小到这个装饰器,发现不知何故ctx在它应该是{}时有价值。

所以我设置了一个断点,然后向上一级,然后我发现它的来电者根本没有传递任何东西。

参数如何具有既不被调用者传递也不传递默认值的值?

2 个答案:

答案 0 :(得分:5)

您正在使用可变参数作为默认参数。每次在没有该参数的情况下调用它时,它将包括您提供的那个,包括先前的修改。请使用None作为默认值,检查它,如果是is None,请在函数正文中指定空dict。

def region_required(view_func):
    def new_view(request, ctx=None, *args, **kw):
        if ctx is None:
            ctx = {}
        import pdb; pdb.set_trace()
        ctx['regions'] = Region.objects.all()
        return view_func(request, context=ctx, *args, **kw)
    return new_view

答案 1 :(得分:0)

ctx很可能被分配了包装函数的第一个arg。您不能拥有关键字arg,后跟* args。就调用者而言,ctx只是另一个arg。

例如:

my_func(request, 1, 2, 3)

将导致ctx被分配1. ctx需要被视为kwargs的一部分。

ctx = kwargs.get('ctx', {})