gpt4 book ai didi

适用于多种情况的 Python 设计模式

转载 作者:太空狗 更新时间:2023-10-29 17:09:32 24 4
gpt4 key购买 nike

编写具有多种条件的验证函数的推荐结构是什么?看这两个例子。第一个看起来很难看,第二个不是很常见,可能是因为 assert 通常用于排除意外行为。有更好的选择吗?

def validate(val):
if cond1(val):
return False
if cond2(val):
return False
if cond3(val)
return False
return True

或者

def validate(val):
try:
assert cond1(val)
assert cond2(val)
assert cond3(val)
return True
except AssertionError:
return False

最佳答案

编写该函数的一种简洁方法是使用 any 和一个生成器表达式:

def validate(val):
conditions = (cond1, cond2, cond3)
return not any(cond(val) for cond in conditions)

anyall 函数短路,所以他们会在有确定结果时立即停止测试,即 any 一旦达到 True-ish 值就停止,all 一旦达到 False-ish 值就停止,所以这种形式的测试非常有效。

我还应该提到,将这样的生成器表达式传递给 all/any 比列表理解更有效。因为 all/any 在获得有效结果后立即停止测试,如果您从生成器提供它们,那么生成器也会停止,因此在上面的代码中如果 cond(val) 评估为 True-ish 值,不会测试进一步的条件。但是如果你传递 all/any 一个列表理解,例如 any([cond(val) for cond in conditions]) 整个列表有在 all/any 甚至可以开始测试之前构建。


你没有向我们展示你的cond函数的内部结构,但是你确实在你的问题中提到了assert,所以我觉得下面的评论是有顺序的在这里。

正如我在评论中提到的,assert 不应用于验证数据,它用于验证程序逻辑。 (此外,可以通过 -O 命令行选项禁用断言处理)。用于具有无效值的数据的正确异常是 ValueError,对于类型错误的对象,使用 TypeError。但请记住,异常旨在处理异常情况。

如果您预计会有大量格式错误的数据,那么使用基于 if 的逻辑通常比使用异常更有效。如果实际上没有引发异常,则 Python 异常处理速度非常快,事实上它比等效的基于 if 的代码更快。但是,如果引发异常的次数超过 5-10%,则基于 try...except 的代码将明显慢于基于 if 的等效代码.

当然,有时使用异常是唯一明智的选择,即使情况并非如此异常。一个典型的例子是,当您将数字字符串的集合转换为实际的数字对象时,表示整数的字符串被转换为整数对象,其他数字字符串被转换为 float ,而其他字符串则保留为字符串。在 Python 中执行此操作的标准方法涉及使用异常。 For example :

def convert(s):
''' Convert s to int or float, if possible '''
try:
return int(s)
except ValueError:
try:
return float(s)
except ValueError:
return s

data = ['42', 'spam', '2.99792458E8']
out = [convert(u) for u in data]
print(out)
print([type(u) for u in out])

输出

[42, 'spam', 299792458.0]
[<class 'int'>, <class 'str'>, <class 'float'>]

使用 "Look Before You Leap"这里的逻辑是可能的,但它使代码更复杂,因为您需要处理可能的减号和科学记数法。

关于适用于多种情况的 Python 设计模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47728364/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com