5

考虑以下代码:

>>> def default_answer():
...     print "Default was required!"
...     return 100
... 
>>> g = { 'name': 'Jordan', 'age': 35 }
>>> result = g.get('age', default_answer())
Default was required!
>>> result = g.pop('age', default_answer())
Default was required!

请注意,无论是否g包含预期的键,都会调用 default_answer。这在编程上是有意义的,但如果default_answer计算成本很高,这将是一件麻烦事(运行大量代码来创建一个将被丢弃的值)。

我能想到写这个而不总是打电话的唯一方法default_answer是:

result = g.pop('age', False) or default_answer()

这是最好的方法吗?

(请注意,我知道default_answer用惰性评估替换对象也可以解决这个问题的一部分,但这超出了这个问题的范围)。

4

2 回答 2

10

不,这不是最好的方法,因为结果g.pop()可能是“假的”。使用try/except代替:

try:
    result = g.pop('age')
except KeyError:
    result = default_answer()

这个成语称为EAFP ,由于各种原因,它通常比LBYL更受欢迎:

  1. 它避免了两次查找密钥(这不是实际的问题dict,但对于其他映射可能不是最佳的)。

  2. 它避免了线程代码中的竞争条件。

  3. 许多人发现它更容易阅读。

于 2012-08-27T18:53:25.217 回答
2

只要您知道任何 boolean-false 值(不仅是 False,还包括空字符串、空列表等)都应该被您的默认值替换,这是一种不错的方式。你总是可以明确地做到这一点:

if 'age' in g:
    result = g['age']
else:
    result = default_answer()

(或具有 try/except 的等效版本,您首先读取值并在 except 子句中执行默认值。哪个更好取决于您期望缺失值的情况是常见的还是不常见的。)

于 2012-08-27T18:53:54.623 回答