Python中的逻辑参数检查

1 投票
4 回答
546 浏览
提问于 2025-04-16 10:16

我不太确定我的问题有没有明确的答案,不过无论如何,我还是想问一下。我正在写一个函数,这个函数有很多参数,每个参数要么是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表单,但其实它可以解析和验证你传给它的任何东西。你可以定义一些模式类,一次性验证所有输入。

撰写回答