克里斯·里德 ( Chris Ried)在Unsplash上摄
有一个古老的笑话是这样的-一个人热切地恳求上帝骑自行车。 即使经过多年的宣传,对方也没有听到任何声音。 于是,那个人偷了一辆自行车,然后向上帝求饶 。
我怀疑某些计算机科学家基于笑话创建了编程原理,但您永远不会知道。 EAFP的简称:比许可更容易获得宽恕,是一种编程原理,遵循上述笑话中所述的类似推理方法。 尽管在现实世界中听起来像是基本原理,但计算机并不关心道德。 他们也没有感觉(还!)。 因此,我们可以安全地遵循这一原则,而不会触发世界末日。
在深入研究细节之前,让我们看一个比喻,它可能使以后更容易理解其技术性。
“永远记住,它更容易道歉比获得许可。 在当今的计算机世界中,最好的办法就是做到这一点。” —格蕾丝·霍珀
行动前思考,飞跃前思考
假设我们在python程序中使用字典,并且需要修改与键关联的值。 在标准情况下,我们要做的第一件事是检查密钥是否存在。 如果某个地方的某人已经从字典中删除了该键,则我们的程序将突然终止并出现KeyError异常。
test_dict = {}
keys = [ 1 , 2 , 3 , 4 ]
values = [ 'a' , 'b' , 'c' , 'd' ]
# the for loop will generate this dictionary -> {1:'a', 2:'b', 3:'c', 4:'d'}
for key, value in zip(keys, values):
test_dict[key] = value
# Now assume you wish to append an 'e' to the pre-existing value associated with key 4
if 4 in test_dict:
test_dict[ 4 ] += 'e'
在修改与键4关联的值之前,我们使用条件语句来验证键是否存在于字典中。 这被称为LBYL原理,是“跳跃前看”的缩写。 我们大多数人都习惯这种编码风格。
危险地生活
我们当中有些人是偶像破坏者。 约定不是我们的事。 我认为Python的开发人员也是如此。 他们已经决定通过引入代码块缩进来挑战这些约定,取代大多数编程语言所采用的花括号的标准方法。 我想知道EAFP是否应该成为Python布丁之上的樱桃。
test_dict = {}
keys = [ 1 , 2 , 3 , 4 ]
values = [ 'a' , 'b' , 'c' , 'd' ]
# the for loop will generate this dictionary -> {1:'a', 2:'b', 3:'c', 4:'d'}
for key, value in zip(keys, values):
test_dict[key] = value
# Now assume you wish to append an 'e' to the pre-existing value associated with key 4
try :
test_dict[ 4 ] += 'e'
except KeyError:
print( 'The key you are trying to modify does not exist' )
在这里,一切看起来都与第一个要点类似,只是到最后的方法略有不同。 在这种情况下,我们不验证密钥是否存在。 我们直接跳入并尝试修改与键关联的值。 如果密钥不存在,则会抛出KeyError异常,我们将根据需要处理该异常。
与时间赛跑
现在,您可能会问-“ EAFP的重点是什么? 如果我可以通过首先验证键的存在来避免异常,那我很好。 您为什么要向我推销新宗教?”
放下干草叉!
EAFP优于LBYL的优点是它避免了经典的竞争条件错误。 为何如此? 好吧,让我们假设在LYBL方法中,在我们检查密钥并修改其值的时间之间,其他一些程序从字典中删除了密钥。 你猜怎么了? 你玩了。 即使该密钥仅存在于几微秒前,它也已被擦除,现在您将遇到KeyError异常。
EAFP通过不参与所有不必要的体操活动来完全绕过此错误。
参考文献:
先前发布在https://medium.com/@jaintj95/easier-to-ask-for-forgiveness-than-permission-a-tale-of-pythons-eccentricity-1992bb6b0764