解压缩参数列表并从web.py中实例化WTForms对象

时间:2012-08-29 07:01:09

标签: python argument-passing web.py wtforms

经过一些搜索后,我发现可以使用以下代码在web.py中实例化一个WTForms对象:

form = my_form(**web.input())

web.input()返回一个“类字典”的web.storage对象,但如果没有双星号,WTForms将引发异常:

TypeError: formdata should be a multidict-type wrapper that supports the 'getlist' method

从Python文档中我了解到两个星号用于解包命名参数的字典。也就是说,我仍然对确切的情况感到困惑。什么使得web.input()返回的web.storage对象“类似于字典”足以使它可以被**解压缩但“类似字典”足以使它可以作为 - 是WTForms的构造函数吗?

我知道这是一个非常基本的问题,但是非常感谢任何帮助新手程序员的建议!

2 个答案:

答案 0 :(得分:3)

the documentation。不同之处在于,func(someDict)传递一个参数,即一个dict。执行func(**someDict)解压缩dict并将每个键/值对作为单独的关键字参数传递。

与“dict-like enough”或不同程度的dict-like-ness无关。 (它与web.py或WTForms没有任何关系。)这两个选项只是两种不同的方式,可以编写一个函数来接受不同种类的参数,以及传递这些参数的两种相应方式。例子:

>> def oneArg(d):
...     print d
>>> def manyArgs(**d):
...     print d
>>> d = {'a': 1, 'b': 2}
>>> oneArg(d)
{'a': 1, 'b': 2}
>>> manyArgs(**d)
{'a': 1, 'b': 2}
>>> manyArgs(a=1, b=2)
{'a': 1, 'b': 2}

最后两个例子特别展示了**d的作用。传递带有**d的dict与将每个键/值对作为单独的关键字参数传递相同。

答案 1 :(得分:1)

来自WTForms source

def process(self, formdata=None, obj=None, **kwargs):
    if formdata is not None and not hasattr(formdata, 'getlist'):
        if hasattr(formdata, 'getall'):
            formdata = WebobInputWrapper(formdata)
        else:
            raise TypeError("formdata should be a multidict-type wrapper that supports the 'getlist' method")

    for name, field, in iteritems(self._fields):
        if obj is not None and hasattr(obj, name):
            field.process(formdata, getattr(obj, name))
        elif name in kwargs:
            field.process(formdata, kwargs[name])
        else:
            field.process(formdata)

您目前将参数传递为**kwargs,但如果您希望formdata能够正常工作,则它应该是多字形类型,而不是常规dict或webpy {{1}因为它们都没有web.storage方法。 getlist是一个dict,它存储同一个键的多个值。

您可以尝试将multidict作为web.input()参数传递,如下所示:obj我认为它应该有效。