Python中的逻辑参数检查
我不太确定我的问题有没有明确的答案,不过无论如何,我还是想问一下。我正在写一个函数,这个函数有很多参数,每个参数要么是None
,要么有一个有限的取值范围。因为我不太相信用户会给我正确的输入,所以我必须检查每个参数的类型,如果它的类型正确(或者是None
),我还想看看它的值是否在正确的范围内。这就意味着我有很多这样的代码:
# size
if isinstance(size, str):
if size in range(4):
self.data[uid]['size'] = int(size)
else:
warnings.warn("ID %s: illegal size %s" % (uid, size))
self.data[uid]['size'] = None
elif size == None:
self.data[uid]['size'] = None
else:
warnings.warn("ID %s: illegal size %s" % (uid, str(size)))
self.data[uid]['size'] = None
等等。由于这些代码变得越来越重复,我在想是否有一个库可以自动化这个过程,抛出异常或警告,并减少代码的重复。
谢谢
4 个回答
1
我会把这个重写成:
# size
if isinstance(size, str):
if size in range(4):
self.data[uid]['size'] = int(size)
else:
warnings.warn("ID %s: illegal size %s" % (uid, size))
self.data[uid]['size'] = None
elif size == None:
self.data[uid]['size'] = None
else:
warnings.warn("ID %s: illegal size %s" % (uid, str(size)))
self.data[uid]['size'] = None
像这样:
if size in ["0", "1", "2", "3"]: # alternative: if size in map(str, range(4)):
self.data[uid]['size'] = int(size)
else:
if size != None:
warnings.warn("ID %s: illegal size %s" % (uid, size))
self.data[uid]['size'] = None
我真心不喜欢的是使用 isinstance(size, str)
这个写法(在Python中,明确检查类型通常是不受欢迎的,因为这很容易破坏鸭子类型的原则)。
这就是为什么你很难找到一个可以自动检查类型的Python库,因为这与Python语言的核心理念相悖。
1
我同意上面的说法:假设size
是正确的类型,如果不是,就让它抛出一个异常(或者返回一个错误)。
不过,当你处理可能会引发异常的输入时,有一个很有用的模式:把输入引发的任何异常包裹起来,这样异常信息中会包含输入的内容。例如,这样你就能得到:
ParseError: while parsing 'number = foo': ValueError: invalid literal for int() with base 10: 'foo'
代码大致是这样的:
try:
parse(input)
catch Exception, e:
raise ParseError("while parsing %r: %r" %(input, e)), None, sys.exc_info()[2]
在raise
的第三个参数中,会使用原始的追踪信息,这样堆栈跟踪会指向实际导致错误的那一行(比如size = int(value)
),而不是指向raise
的调用。
1
我在想,是否有一个库可以自动化这个过程,抛出异常/警告,并减少代码的重复。
我使用formencode来处理这类事情。虽然它看起来只是用来解析HTML表单,但其实它可以解析和验证你传给它的任何东西。你可以定义一些模式类,一次性验证所有输入。