Python中的EAFP原理是什么?

Unp*_*les 123 python principles

Python中"使用EAFP原理"是什么意思?你能提供任何例子吗?

Sve*_*ach 195

词汇表:

比许可更容易请求宽恕.这种常见的Python编码风格假设存在有效的键或属性,并且如果假设被证明是错误则捕获异常.这种干净,快速的风格的特点是存在许多tryexcept陈述.该技术与许多其他语言(如C)共有的LBYL风格形成对比.

一个例子是尝试访问字典密钥.

EAFP:

try:
    x = my_dict["key"]
except KeyError:
    # handle missing key
Run Code Online (Sandbox Code Playgroud)

LBYL:

if "key" in my_dict:
    x = my_dict["key"]
else:
    # handle missing key
Run Code Online (Sandbox Code Playgroud)

LBYL版本必须在字典内搜索两次密钥,也可能被认为稍微不那么可读.

  • 一个改进是另一个优点是避免竞争条件...例如,只是尝试打开一个文件,如果你得到它,你得到它.而不是看到*如果你能得到它*,然后尝试获得它,并意识到在检查和访问尝试之间的微不足道的时间量,你可以更长时间得到它. (29认同)
  • Python还提供了一种避免这两种方法的方法,如果处理程序只是在键不存在时将默认值赋给`x`:`x = mydict.get('key')`将返回`None`如果`'key'`不在`my_dict`中; 你也可以做`.get('key',<something>)`,然后如果键不在字典中,那么x将被分配.`dict.setdefault()`和`collections.defaultdict`也是避免多余代码的好东西. (22认同)
  • @ski这是一个稍微不同的问题.你应该_always_尽可能地保持try块,以避免捕获错误的异常.另请注意,我通常不喜欢EAFP风格.我只是在这里回答这个问题,并说有些人更喜欢它.我根据具体情况来判断哪些代码对我来说最易读. (4认同)
  • 我认为值得一提的是 [Grace Hopper](https://en.wikipedia.org/wiki/Grace_Hopper) 可能是这句话的来源,她引用了一句话:“敢于做。请求宽恕更容易而不是获得许可”(不限于编程)。 (3认同)
  • 我认为 ` except KeyError` 和 `AttributeError` 都很简单,但却是一些最糟糕的例子。很多次我被困在调试某些东西上,因为“ except AttributeError”被放置在错误的位置,最终捕获了链中更深处引发的错误属性错误。我认为更好的例子是:`try: open() ... except: IOError`。或者 `尝试:parseLine() ... except ParseError` (2认同)

Apo*_*tne 6

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

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

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")
Run Code Online (Sandbox Code Playgroud)

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())
Run Code Online (Sandbox Code Playgroud)

  • @ ds4940如果文件可访问性在第6行和第7行之间发生更改,即在检查文件是否可访问与打开文件之间,这是竞争条件。 (2认同)

Eng*_*eer 5

我称之为"乐观编程".这个想法是,大多数时候人们会做正确的事情,错误应该很少.所以代码首先要发生"正确的事情",然后如果不这样做就抓住错误.

我的感觉是,如果用户要犯错误,他们应该是遭受时间后果的人.以正确方式使用该工具的人将加速通过.

  • 或者“try-catch”而不是“if-else” (2认同)