Python中的EAFP原理是什么?


Answers:


215

词汇表中

寻求宽恕比允许容易。这种通用的Python编码风格假设存在有效的键或属性,并且在假设被证明为假的情况下捕获异常。这种干净快捷的样式的特点是存在许多tryexcept声明。该技术与C等其他许多语言通用的LBYL风格形成对比。

一个示例是尝试访问字典键。

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版本必须在字典中搜索关键字两次,并且可能还被认为可读性较差。


34
增强之处在于,另一个优势是避免了竞争条件……例如,只需打开一个文件,如果得到,就可以了。而不是查看是否可以获取它,然后尝试在以后获取它,并意识到在检查和访问尝试之间的极短时间内,您可以更长久地获取它。
乔恩·克莱门茨

23
如果处理程序只是将默认值分配给x键不存在时,Python还提供了一种避免这两种方法的方法:如果not in ,x = mydict.get('key')则返回;您也可以这样做,然后如果键不在字典中,则x将被分配一些东西。而对于避免过多的代码以及好东西。None'key'my_dict.get('key', <something>)dict.setdefault()collections.defaultdict
JAB

1
我认为except KeyErrorAttributeError很简单,但是有些最坏的例子。很多次,我被困在调试某些东西是因为except AttributeError放置在错误的地方,最终导致错误的属性错误在链的更深层出现。我认为更好的例子是:try: open() ... except: IOError。或try: parseLine() ... except ParseError
滑雪

4
@ski这是一个稍微不同的问题。您应该始终将try块保持尽可能的小,以避免捕获错误的异常。另请注意,我通常不喜欢EAFP风格。我只是在这里回答这个问题,并指出有些人喜欢它。我会根据具体情况决定对我而言最可读的代码。
Sven Marnach '17

1
我认为值得一提的是,格蕾丝·霍珀Grace Hopper)可能是这句话的来源,她的话是:“敢做”。寻求宽恕比获得许可要容易得多”(不仅限于编程)。
法比恩·斯诺瓦特

9

我将尝试通过另一个示例对其进行解释。

在这里,我们尝试访问文件并在控制台中打印内容。

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

3
@ ds4940如果文件可访问性在第6行和第7行之间发生更改,即在检查文件是否可访问与打开文件之间,这是竞争条件。
Markus von Broady,

@MarkusvonBroady同意,编辑了答案,以提供其他参加比赛的参与者的示例。
ds4940

6

我称之为“乐观编程”。这个想法是,大多数时候人们会做正确的事,错误应该很少。因此,首先编写代码以使“正确的事情”发生,然后,如果没有,则捕获错误。

我的感觉是,如果用户要犯错误,那么他们应该是遭受时间后果的人。正确使用该工具的人会被激怒。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.