关于python:验证和异常与错误消息元组

Validation and exception vs. error message tuple

我正在研究一个验证函数。我知道异常用于错误和意外情况,但是在验证函数的情况下,如果内部没有满足某个条件,我希望它返回False,而不是异常。

问题是,在验证完成后,我需要用一条消息来提升一个消息窗口,比如:"Tool exited because X condition not met"。我的工作流程是返回包含结果和消息的元组:

1
(True, Y_message)

或(错误,不满足x条件)

然后:

1
2
3
a, b = result
if not a:
    raise_window(message=b)

然而,最近我偶然发现了许多答案,引起了关于这个问题的争论,我很困惑。例如,有人说总是例外:用Python函数返回多个值的最佳方法是什么?还有人说,元组是在Python中实现错误与成功的返回值最佳实践的方法。

如果有人能给我指明正确的方向,我将不胜感激。


验证时,函数的目的是告诉您是否满足条件。您期望得到一个布尔结果;有效或无效。如果不支持对函数的输入,或者不满足对验证过程本身的某些依赖性,那么只会抛出错误。在这种情况下,验证程序的正常操作无法完成,在这种情况下,您不能返回valid或not valid,因为验证程序无法做出该决定。

您可以将它与isinstance()issubclass()进行比较;这两个函数测试一个值与另一个值。它们返回TrueFalse,如果您给它们不支持的输入,则会引发异常:

1
2
3
4
5
6
>>> isinstance(1, int)
True
>>> isinstance(1, 'foobar')
Traceback (most recent call last):
  File"<stdin>", line 1, in <module>
TypeError: isinstance() arg 2 must be a class, type, or tuple of classes and types

正常操作是验证,不支持输入意味着不能返回有效或无效的值,因此保证出现异常。

因此,对于返回(True, message)(False, message)元组的验证器,我只会在验证过程本身存在问题时提出异常,而不是指出(False, message)情况。

注意,验证器返回什么并不重要;如果您需要同时返回一个有效/无效标志和相应的消息(并且只有验证器可以生成该消息),那么返回一个元组就可以了。

您也可以返回自定义类:

1
2
3
4
5
6
7
8
9
10
11
12
class ValidationResult(object):
    def __init__(self, result, message=''):
        self.result = bool(result)
        self.message = message

    def __nonzero__(self):  # Python 2
        return self.result

    __bool__ = __nonzero__  # Python 3

    def __str__(self):
        return self.message

然后将其用作测试:

1
2
3
valid = validation(value)
if not valid:
    raise_window(message=str(valid))

使用异常来指示无效数据是这个问题的惯用的、规范的、Python解决方案。考虑int()函数,如果传递无效数据,则会发生异常:

1
2
3
4
>>>> int('abc')
Traceback (most recent call last):
  File"<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: 'abc'