Dict.get() - аргумент по умолчанию оценивается даже после успеха

Почему значение по умолчанию в dict.get(key[, default]) оценивается, даже если ключ находится в словаре?

>>> key = 'foo'
>>> a={}
>>> b={key:'bar'}
>>> b.get(key, a[key])
Traceback (most recent call last):
  File "<pyshell#5>", line 1, in <module>
    b.get(key, a[key])
KeyError: 'foo'

Ответы

Ответ 1

Как и в любом вызове функции, аргументы вычисляются до того, как выполняется вызов.
В этом случае dict.get() не является исключением...

Ответ 2

Вы можете переписать пример, который вы указали как

b.get(key, a.get(key))

чтобы избежать исключения. Это вернет None, если ключ не содержит ни слова. В более общем плане, если вы хотите избежать оценки второго аргумента, вы можете использовать

try:
    x = b[key]
except KeyError:
    x = a[key]   # or whatever the default value is supposed to be

Ответ 3

Потому что вы его оцениваете, а затем передаете его как аргумент get. Это происходит, если заканчивается использование get с использованием аргумента.

Ответ 4

используйте это вместо

x = b.get(key) or a.get(key)

or и and являются операторами короткого замыкания, поэтому, если b имеет ключ, он не будет смотреть на a. Но проблемы возникнут, если у вас есть falsy значения в b. Если это так, вы можете сделать.

x = b[key] if key in b else b.get(a)

Ответ 5

Чтобы избежать поиска, вы могли:

value = b.get(key)
if value is None:
   value = a[key]

Или если None разрешено, то:

not_set = object()
# ...
value = b.get(key, not_set)
if value is not_set:
   value = a[key]

Ответ 6

  • a[key] есть a['foo'], и у вас нет этого ключа в a.
  • это оценивается перед вызовом b.get, следовательно, ошибка
  • ", даже если ключ находится в словаре" - это anot true, b пуст (но, как показывает 2. указывает, это не имеет значения)