Python中的EAFP原理是啥?
Posted
技术标签:
【中文标题】Python中的EAFP原理是啥?【英文标题】:What is the EAFP principle in Python?Python中的EAFP原理是什么? 【发布时间】:2012-07-06 19:59:44 【问题描述】:在 Python 中“使用 EAFP 原则”是什么意思?你能提供任何例子吗?
【问题讨论】:
不符合 Guido:mail.python.org/pipermail/python-dev/2014-March/133118.html 【参考方案1】:来自glossary:
请求宽恕比请求许可更容易。这种常见的 Python 编码风格假设存在有效的键或属性,如果假设被证明是错误的,则捕获异常。这种简洁快速的风格的特点是存在许多
try
和except
语句。该技术与许多其他语言(如 C)常见的LBYL style 形成对比。
一个例子是尝试访问字典键。
EAFP:
try:
x = my_dict["key"]
except KeyError:
# handle missing key
LBYL:
if "key" in my_dict:
x = my_dict["key"]
else:
# handle missing key
LBYL 版本必须在字典中搜索两次键,并且可能也被认为可读性稍差。
【讨论】:
一个改进是另一个优点是避免竞争条件......例如,只需尝试打开一个文件,如果你得到它,你就会得到它。而不是看到如果你能得到它,然后试图得到它并意识到在检查和访问尝试之间的极短时间里,你可以更长的时间得到它。 Python 还提供了一种避免这两种情况的方法,如果处理程序只是在密钥不存在时为x
分配默认值:x = mydict.get('key')
将返回 None
如果'key'
不在my_dict
中;你也可以做.get('key', <something>)
,然后如果键不在字典中,x 将被分配一些东西。 dict.setdefault()
和 collections.defaultdict
也是避免过多代码的好东西。
我认为except KeyError
和AttributeError
很简单,但也有一些最糟糕的例子。很多次我因为except AttributeError
被放置在错误的位置而被困在调试某些东西上,这最终导致了在链中更深层次的错误属性错误。我认为更好的例子是:try: open() ... except: IOError
。或try: parseLine() ... except ParseError
@ski 这是一个稍微不同的问题。您应该始终尽量减少 try 块,以避免捕获错误的异常。另请注意,我通常不喜欢 EAFP 样式。我只是在这里回答这个问题,并说明有些人更喜欢它。我会根据具体情况决定哪种代码对我来说最易读。
我认为值得一提的是,Grace Hopper 可能是这句话的来源,她引用了她的话:“敢于行动。请求宽恕比获得许可更容易”(不限于编程)。【参考方案2】:
我将尝试用另一个例子来解释它。
这里我们尝试访问文件并在控制台中打印内容。
LBYL - 三思而后行:
我们可能想检查我们是否可以访问该文件,如果可以,我们将打开它并打印内容。如果我们无法访问该文件,我们将点击else
部分。这是一个竞争条件的原因是因为我们首先进行了访问检查。当我们到达with open(my_file) as f:
时,可能由于某些权限问题(例如另一个进程获得了独占文件锁),我们无法再访问它。这段代码可能会抛出一个错误,我们将无法捕捉到该错误,因为我们认为我们可以访问该文件。
import os
my_file = "/path/to/my/file.txt"
# Race condition
if os.access(my_file, os.R_OK):
with open(my_file) as f:
print(f.read())
else:
print("File can't be accessed")
EAFP - 请求宽恕比请求许可更容易:
在这个例子中,我们只是试图打开文件,如果我们不能打开它,它会抛出一个IOError
。如果可以,我们将打开文件并打印内容。因此,我们不是要求,而是尝试去做。如果它有效,那就太好了!如果没有,我们会捕获错误并进行处理。
# # No race condition
try:
f = open(my_file)
except IOError as e:
print("File can't be accessed")
else:
with f:
print(f.read())
【讨论】:
我不确定将其描述为竞争条件是否正确。该文件是否可访问。 @ds4940 如果文件可访问性在第 6 行和第 7 行之间发生变化,即在检查文件是否可访问和打开文件之间发生变化,这是竞争条件。 @MarkusvonBroady 同意,编辑答案以提供比赛条件中其他参与者的示例。 我一直认为 LBYL 是首选的做事方式,而不是try, except
块,对吗?
@SurpriseDog 可能是其他语言,但不是 Python。 Python 期望您使用异常,因此它已被优化为在不引发异常时高效。异常提高了可读性,因为错误处理代码在工作代码之后组合在一起,并且在需要在线处理每个可能的错误时减少了缩进量。【参考方案3】:
我称之为“乐观编程”。这个想法是大多数时候人们会做正确的事情,错误应该很少。因此,首先编写代码以使“正确的事情”发生,然后在错误发生时捕获错误。
我的感觉是,如果用户要犯错误,他们应该是承担时间后果的人。以正确方式使用该工具的人会被快速通过。
【讨论】:
或“try-catch”而不是“if-else” 我的意思是寻找可能的已知错误,例如电话号码字段中的邮政编码。错误应该被正确处理,而不是通过 catch 例程。以上是关于Python中的EAFP原理是啥?的主要内容,如果未能解决你的问题,请参考以下文章
java 中的修饰符transient是啥意识他的原理是啥?
快照测试的工作原理以及 toMatchSnapshot() 函数在 React 组件的 Jest 快照测试中的作用是啥?