为什么在Python中“更容易请求宽恕而不是获得权限”?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么在Python中“更容易请求宽恕而不是获得权限”?相关的知识,希望对你有一定的参考价值。
为什么“更容易请求宽恕而不是获得权限”(EAFP)被认为是Python中的好习惯?作为编程新手,我的印象是,与使用其他检查相比,使用许多try...except
例程将导致臃肿且可读性较低的代码。
EAFP方法的优势是什么?
注意:我知道这里有类似的问题,但它们主要是指一些具体的例子,而我对这个原则背后的哲学更感兴趣。
LBYL,EAFP的反制方法与断言没有任何关系,它只是意味着你在尝试访问可能不存在的东西之前添加一个检查。
Python是EAFP的原因与其他语言(例如Java)不同 - 在Python中捕获异常是相对便宜的操作,这就是为什么鼓励你使用它。
EAFP示例:
try:
snake = zoo['snake']
except KeyError as e:
print "There's no snake in the zoo"
snake = None
LBYL的示例:
if 'snake' in zoo:
snake = zoo['snake']
else:
snake = None
你在这里混合两件事:断言和基于EAFP的逻辑。
断言用于验证函数的约定,即它的前后条件,有时还有它的不变量。它们确保以应该使用的方式使用函数。它们不适用于代码流,因为它们完全中断了错误执行。一个常见的例子是检查函数调用中的None
参数。
在Python中,通常避免使用过多的断言。通常,您应该希望代码的用户正确使用它。例如,如果您记录一个函数来获取不是None
的参数,那么就没有必要使用一个验证该参数的断言。相反,只是期望有一个价值。如果由于None值而出现错误,那么无论如何它都会冒泡,因此用户知道他们做错了什么。但你不应该一直检查所有内容。
现在,EAFP是不同的东西。它用于控制流程,或者更确切地说,它避免了额外的控制流程,有利于期望事情正确并且如果不是则捕获异常。显示差异的常见示例是字典中的密钥访问:
# LBYL
if key in dic:
print(dic[key])
else:
handleError()
# EAFP
try:
print(dic[key])
except KeyError:
handleError()
现在看起来非常相似,但你应该记住LBYL解决方案检查字典两次。与捕获异常的所有代码一样,只有在不存在密钥的情况下才应该这样做。因此,如果通常情况下,提供的密钥不在字典中,那么它是EAFP,您应该直接访问它。如果你不希望密钥存在于字典中,那么你应该首先检查它的存在(虽然异常在Python中更便宜,但它们仍然不是免费的,所以请保留它们以用于特殊情况)。
EAFP的好处还在于你的库或应用程序的逻辑更深层次,key
来自上面,你可以假设这里传递了一个有效的密钥。所以你不需要在这里捕获异常,只是让它们冒泡到代码中的更高点,然后你可以处理错误。这使您可以完全免除这些检查的低级功能。
好问题! StackOverflow中很少有人质疑“原则背后的哲学”。
关于EAFP definition in Python glossary,我甚至会更进一步说它提到“如果假设证明是错误的,则缓存异常”在这种情况下有些误导。因为,让我们面对它,下面的第二个代码片段看起来不那么“干净和快速”(在上述定义中使用的术语)。难怪OP问这个问题。
# LBYL
if key in dic:
print(dic[key])
else:
handleError()
# EAFP
try:
print(dic[key])
except KeyError:
handleError()
我想说,EAFP闪耀的真正时刻是,你根本不写try ... except ...
,至少在你的大多数底层代码库中都没有。因为,the first rule of exception handling: do not do exception handling。考虑到这一点,现在,让我们将第二个片段重写为:
# Real EAFP
print(dic[key])
现在,这不是真正的EAFP方法干净而快速吗?
以上是关于为什么在Python中“更容易请求宽恕而不是获得权限”?的主要内容,如果未能解决你的问题,请参考以下文章
python 使用这一个函数在python中运行sha512哈希文本。为什么sha512?为什么在做这件事的整个过程中你会做得更少