停止文件验证的 Pythonic 方式

Pythonic way to stop file validation

我正在编写一个脚本来验证 csv 文件。我有几个函数可以做一些事情,比如检查某个字段是否低于某个阈值,或者检查是否有任何 NaN 值。

这些函数 return(True) 如果检查通过,return(False) 否则。

我正在尝试找出 correct/pythonic 一旦其中一项检查失败并且 returns False 就停止处理的方法。

我试过 while True,但这只会评估循环中最后一个值 returned。感谢您的帮助!

#I have functions that validate certain things in a csv file
#those functions return(True) if they pass the test, return(False) otherwise.

#I want to be able to call these functions and have the file stop 
#processing once a False is returned.

def function1():
    return(True)
def function2():
    return(True)
def function3():
    return(False)
def function4():
    return(True)

#works, but not pythonic.
checkpoint1 = function1()
if checkpoint1 == True:
    checkpoint2 = function2()
    if checkpoint2 == True:
            checkpoint3 = function3()
            if checkpoint3 == True:
                checkpoint4 = function4()
                if checkpoint4 == True:
                    print("all checkpoints passed")
                else:
                    print("Fail 4")
            else:
                print("Fail 3")
    else:
        print("Fail 2")
else:
    print("Fail 1")

将函数合并到一个列表中,然后遍历该列表以调用每个函数,如果失败则提前中断。

for i, f in enumerate([function1, function2, function3, function4], start=1):
    if not f():
        print(f"Fail {i}")
        break
else:
    print("all checkpoints passed")

如果你不想要输出,你可以简单地使用 all:

if all(f() for f in [function1, function2, function3, function4]):
    print("all checkpoints passed")
else:
    print("One checkpoint failed")

假设“Fail x”消息是更多描述性错误的替代品,您可以使用字典将它们映射到它们的函数,然后在需要时进行迭代和打印。

checkpoints = {
    function1: "Fail 1",
    function2: "Fail 2",
    function3: "Fail 3",
    function4: "Fail 4",
    }

for f in checkpoints:
    if not f():
        print(checkpoints[f])
        break
else:  # no break
    print('all checkpoints passed')

输出:Fail 3

如果您使用的是 Python 3.6 或更早版本,dict 不能保证保持顺序,因此您可以使用 OrderedDict 或元组列表 (function, error).

有多种方法可以处理此类问题。

最简单的是,只为所有组合检查创建一个函数,一旦发现问题就提前退出。

def validate_file(args):
    if not function1():
       print("Fail 1")
       return False

    if not function2():
       print("Fail 2")
       return False

    if not function3():
       print("Fail 3")
       return False

    if not function3():
       print("Fail 3")
       return False

    print("all checkpoints passed")
    return True

然后你可以只调用函数 validate_file,它 returns False 如果某些检查失败与否。这样,您就没有深度嵌套的缩进。


可能更 Pythonic 是使用异常。 如果出现问题,各个函数可以抛出异常,而不是返回 TrueFalse。如果出现错误,您可以捕获那些。例如。类似的东西:

def function2():
   # code
   some_check_failed = True
   if some_check_failed:
      raise FileNotFoundError("fail 2")
   # code

try:
    function1()
    function2()
    function3()
    function4()
except FileNotFoundError as e:
    print(f"File not found: {e}")
except Exception as e:
    print(f"Unknown error: {e}")

如果打印哪个函数失败的 else 语句不是必需的,您也可以将所有内容放入 if 语句中:

if f1() and f2() and f3() and f4(): print(all checkpoints passed)

如果其中一个条件不成立,则其他条件不会执行。例如,这段代码:

def f1():
    print(1)
    return True
def f2():
    print(2)
    return False
def f3():
    print(3)
    return True

if f1() and f2() and f3():
    print("Hi")
else:
    print("Bye")

具有以下输出:1 2 Bye

因为 f3() 没有 运行 因为 f2() 失败了。

如果您想描述哪个条件失败(这总是很好),您可以将 logging/print 语句放在检查条件的实际函数中。

例如:

def f3():
    #If f3 fails
    print("F3 condition failed")

    return False