键入检查http-post参数Python;

Type checking for http-post arguments Python; Using types as values in a dictionary

对于我正在编写的API,我想编写一个"check-params"方法,以确保在HTTP POST请求主体中传递的参数能够被适当地类型化。

例如,假设我正在传递一个参数"纬度"。然后,

1
    'latitude'='thisisnotafloat'

应给出错误,而

1
    'latitude'='43.21'

不应引发错误。

要处理多个参数,创建类型为值的字典是否有任何错误:

1
2
3
4
5
6
    required_types = {
            'arg1':str,
            'arg2':int,
            'arg3':str,
            'arg4':float
    }

然后执行duck类型(为了简化问题,假设我处理的是一个必需的arg根本没有被传入的情况,类型检查只在存在性检查之后发生)。

1
2
3
4
5
    for arg, type_ in required_types.iteritems():
        try:
            type_(self.get_argument(arg))    #using tornado here to get body arg
        except:
            handle_invalid_type_error()

或者,我可以将类型存储为字符串,并使用eval()函数。例如。,

1
2
3
4
5
6
7
8
9
10
11
12
     required_types = {
            'arg1':'str',
            'arg2':'int',
            'arg3':'str',
            'arg4':'float'
    }

    for arg, type_ in required_types.iteritems():
        try:
            eval(type_)(self.get_argument(arg))  #using tornado here to get body arg
        except:
            handle_invalid_type_error()

这里有明确的赢家吗?或者另一个更好的方法?


推荐的("pythonic")方法是在需要时进行转换,如果转换失败,则会引发错误。除非在程序的后期处理错误是非常不方便的,否则我根本不需要使用check_params方法。

另外,我认为将类型存储为字符串和使用eval的类型绝对没有好处。如果您是动态获取类型的,那么当然可以使用eval,否则它会添加一个额外的处理步骤,尽管它的成本可以忽略不计,但毫无用处。一般来说,除非你真的需要,否则最好远离eval(从安全的角度来看,这只是一个好的心态)。


大卫的回答也是我的一般建议。

如果你真的需要事先检查这些论点——有时有理由这样做——你的第一个方法基本上是好的。不过,有两条评论:

  • 你不应该使用裸露的except条款。它还将捕获您最肯定不想在这里捕获的异常,如SystemExit。在给定的例子中,裸露的except子句也会捕获由错误的参数查找导致的KeyError或其他内容,这可能会导致相当无用的错误消息。如果要检查的类型是内置的python类型,那么捕获ValueError就足够了。如果ValueError还不够,那么except Exception几乎总是比光秃秃的except条款好,因为它不会抓住GeneratorExitKeyboardInterruptSystemExit

  • 在您的示例中,您还检查了str。这总是成功的,因为您正在检索的值是字符串,所以检查是否可以将它们转换为字符串是没有意义的。


  • 我对其他评论(到目前为止)的看法不同。我认为,公开一个执行正确错误检查并报告清晰的描述性错误消息(甚至是错误列表)的API是让第三方使用您的API的关键点。

    此外,您可以一次完成验证,并将重点放在实际工作上:逻辑。

    现在回答你的问题:

    你看过这个要点吗:https://gist.github.com/anonymous/850704?

    您可以使用验证器函数、类型检查和相等性检查进行验证。如果你用它来驱动你的API,它很适合龙卷风。

    如果您正在寻找某种模式声明性的东西,可以查看https://pypi.python.org/pypi/voluptuous演示一个示例


    你有机会使用wtforms吗?如果不是的话,不妨看看它是如何为您的API实现验证器的。