假设connectionDetails是一个Python字典,那么像这样重构代码的最佳、最优雅、最“Python”的方式是什么呢?

if "host" in connectionDetails:
    host = connectionDetails["host"]
else:
    host = someDefaultValue

当前回答

这并不是我们要问的问题,但是在python字典中有一个方法:dict.setdefault

    host = connectionDetails.setdefault('host',someDefaultValue)

然而,这个方法将connectionDetails['host']的值设置为someDefaultValue,如果key host还没有定义,这与问题不同。

其他回答

我相信所有这些答案都是可以的,但这表明没有“好”的方法来做到这一点。我一直使用字典而不是case语句,并添加一个默认子句,我只是调用以下函数:

def choose(choise, choises, default):
    """Choose a choice from the choises given
    """
    return choises[choise] if choise in choises else default

这样我就可以使用正常的字典,没有特殊的默认子句等。

你也可以像这样使用defaultdict:

from collections import defaultdict
a = defaultdict(lambda: "default", key="some_value")
a["blabla"] => "default"
a["key"] => "some_value"

你可以传递任何普通函数而不是lambda:

from collections import defaultdict
def a():
  return 4

b = defaultdict(a, key="some_value")
b['absent'] => 4
b['key'] => "some_value"

(这是一个迟来的回答)

另一种方法是继承dict类的子类并实现__missing__()方法,如下所示:

class ConnectionDetails(dict):
    def __missing__(self, key):
        if key == 'host':
            return "localhost"
        raise KeyError(key)

例子:

>>> connection_details = ConnectionDetails(port=80)

>>> connection_details['host']
'localhost'

>>> connection_details['port']
80

>>> connection_details['password']
Traceback (most recent call last):
  File "python", line 1, in <module>
  File "python", line 6, in __missing__
KeyError: 'password'

是这样的:

host = connectionDetails.get('host', someDefaultValue)

这并不是我们要问的问题,但是在python字典中有一个方法:dict.setdefault

    host = connectionDetails.setdefault('host',someDefaultValue)

然而,这个方法将connectionDetails['host']的值设置为someDefaultValue,如果key host还没有定义,这与问题不同。