对 http-post 参数进行类型检查 Python;使用类型作为字典中的值
对于我正在编写的 API,我想编写一个“check_params”方法,以确保能够对 http-post 请求正文中传递的参数进行适当的类型转换。
例如,假设我传递一个参数“纬度”。 然后,
'latitude'='thisisnotafloat'
应该给出错误,而
'latitude'='43.21'
不应抛出错误。
要处理多个参数,创建一个以类型为值的字典有什么问题吗:
required_types = {
'arg1':str,
'arg2':int,
'arg3':str,
'arg4':float
}
然后执行鸭子打字(为了简化问题,假设我正在处理所需参数根本没有传入的情况并且类型检查仅在存在检查之后发生)。
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() 函数。 例如,
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()
这里有明显的赢家吗?或者另一种更好的方法?
For an API that I'm writing, I'd like to write a 'check_params' method that ensures arguments passed in the body of an http-post request are able to be appropriately typecasted.
For example, suppose I am passing an argument 'latitude'.
Then,
'latitude'='thisisnotafloat'
should give an error, while
'latitude'='43.21'
should not throw an error.
To handle multiple arguments, is there anything wrong with creating a dictionary with types as the values:
required_types = {
'arg1':str,
'arg2':int,
'arg3':str,
'arg4':float
}
and then performing duck-typing (for simplification of the question, assume I'm handling the case where a required arg does not get passed in at all and type checking only occurs after an existence check).
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()
Alternatively, I could store the types as strings and use the eval() function.
E.g.,
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()
Is there a clear winner here? Or another superior approach?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
推荐的(“Pythonic”)方法是在需要时进行转换,如果失败则抛出错误。除非在程序的后期处理错误非常不方便,否则我根本不会使用
check_params
方法。另外,我认为将类型存储为字符串并对其进行评估绝对没有任何优势。如果您要动态获取类型,那么当然可以使用 eval,但否则它会增加一个额外的处理步骤,尽管其成本可以忽略不计,但没有任何作用。通常最好远离
eval
,除非您真的需要它(从安全角度来看只是一个良好的心态)。The recommended ("Pythonic") way to do this is to just do the conversion when you need to, and raise an error if it fails. Unless it's massively inconvenient to deal with an error in a later stage of the program, I wouldn't bother with a
check_params
method at all.Also, I see absolutely no advantage to storing the types as strings and
eval
ing them. If you were getting the types dynamically, then sure, you could useeval
, but otherwise it adds an extra processing step that, although it comes at a negligible cost, serves no purpose. and it's generally better to stay away fromeval
unless you really need it (just a good mindset to get into from a security standpoint).大卫的回答也是我的一般建议。
如果您确实需要事先检查参数(有时有有理由这样做),那么您的第一种方法基本上就可以了。不过有两条评论:
您不应该使用裸露的
except
子句。它还会捕获您肯定不想在此处捕获的异常,例如SystemExit
。在给定的示例中,裸露的except
子句也会捕获由于参数查找失败而导致的KeyError
(或其他),这可能会导致相当无用的错误信息。如果您要检查的类型是内置的 Python 类型,捕获ValueError
就足够了。如果ValueError
还不够,except Exception
几乎总是比裸露的except
子句更好,因为它不会捕获GeneratorExit
、KeyboardInterrupt
和SystemExit
。在您的示例中,您还检查
str
。这总是会成功,因为您检索的值是字符串,因此检查是否可以将它们转换为字符串有点毫无意义。David's answer would be my general advice, too.
If you really need to check the arguments beforehand – sometimes there are reasons to do so – your first approach is basically fine. Two comments, though:
You shouldn't use a bare
except
clause. It will also catch exceptions you most certainly don't want to catch here, likeSystemExit
. In the given example, the bareexcept
clause would also catch aKeyError
(or whatever) resulting from a failing argument look-up, which would probably lead to a rather unhelpful error message. If the types you are checking for are built-in Python types, catchingValueError
should be enough. IfValueError
isn't enough,except Exception
is almost always better than a bareexcept
clause, since it won't catchGeneratorExit
,KeyboardInterrupt
andSystemExit
.In your example, you also check for
str
. This will always succeed because the values you are retrieving are strings, so it's a bit pointless to check if you can convert them to strings.您有机会使用 WTForms 吗?如果没有,那么可能值得看看它如何为您的 API 实现验证器。
Any chance you could use WTForms? If not, it might be worth having a look at how it implements validators for your API.
我不同意其他评论的相同观点(到目前为止)。我认为,公开一个进行适当错误检查并报告清晰的描述性错误消息(甚至错误列表)的 API,是让第三方使用您的 API 的关键点。
此外,您可以一次性完成验证,并可以专注于真正的工作:逻辑。
现在回答你的问题:
你看一下这个要点吗: https://gist.github.com/anonymous/ 850704?
您可以使用验证器函数、类型检查、相等性检查进行验证。如果您曾经使用它来为您的 API 提供支持,那么它非常适合龙卷风。
如果您正在寻找模式声明性的内容,您可以查看https: //pypi.python.org/pypi/volupteous#show-me-an-example
I don't share the same point of view of the other comments (so far). I think that exposing an API that does a proper error checking and report a clear, descriptive error message (or even a list of errors), is a crucial point to get your API used by third parties.
Moreover, you get the validation out of the way once for all and can focus on the real work : the logic.
Now to answer your question:
Have you look at this gist : https://gist.github.com/anonymous/850704 ?
You can validate using a validator function, a type checking, an equality checking. It fits well in tornado if you ever use it to power your API.
If you are looking for something mode declarative, you can have a look at https://pypi.python.org/pypi/voluptuous#show-me-an-example