2

经过一番搜索,我发现可以使用以下代码在 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 构造函数?

我知道这是一个非常基本的问题,但是任何可以帮助新手程序员的建议都将不胜感激!

4

2 回答 2

3

请参阅文档。不同之处在于,doingfunc(someDict)传递了一个论点,即 dict。解压func(**someDict)dict 并将每个键/值对作为单独的关键字参数传递。

差异与“足够像dict”或不同程度的dict-like-ness无关。(它也与web.pyWTForms 无关。)这两个选项只是可以编写函数以接受不同类型参数的两种不同方式,以及传递这些参数的两种相应方式。例子:

>> 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它的作用。传递 dict 与**d传递每个键/值对作为单独的关键字参数相同。

于 2012-08-29T07:03:50.893 回答
1

来自WTForms 来源

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工作,那么它应该是 multidict-type ,不像常规dict或 webpy web.storage,因为它们都没有getlist方法。multidict是一个为同一个键存储多个值的字典。

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

于 2012-08-29T09:27:04.480 回答