Идиоматический питон, управление аргументами по умолчанию в функциях
Я обычно сталкиваюсь с тем, что большинство людей управляют значениями аргументов по умолчанию в функциях или методах следующим образом:
def foo(L=None):
if L is None:
L = []
Однако я вижу, что другие люди делают что-то вроде:
def foo(L=None):
L = L or []
Я не знаю, если что-то упустил, но почему большинство людей используют первый подход вместо второго? Одинаково ли они одно и то же? Кажется, что второе яснее и короче.
3 ответа
Они не равны. Первый подход проверяет, что именно задано L
является None
, Во-вторых, проверяется, что L истинно в Python. В Python, если вы проверяете список условий, правила следующие:
- Список пуст, значит Ложь
- Правда иначе
Так в чем же разница между упомянутыми подходами? Сравните этот код.
Первый:
def foo(L=None):
if L is None:
L = []
L.append('x')
return L
>>> my_list = []
>>> foo(my_list)
>>> my_list
['x']
Во-вторых:
def foo(L=None):
L = L or []
L.append('x')
return L
>>> my_list = []
>>> foo(my_list)
>>> my_list
[]
Так что сначала не создавайте новый список, он использовал данный список. Но второй создает новый.
Эти два значения не эквивалентны, если аргумент имеет значение false-y. Это не имеет большого значения, так как многие значения false-y не являются подходящими аргументами для большинства функций, где вы делаете это. Тем не менее, существуют мыслимые ситуации, в которых это может иметь значение. Например, если функция должна заполнять словарь (создавая новый, если ничего не задано), и вместо этого кто-то пропускает пустой упорядоченный словарь, то последний подход неправильно возвращает обычный словарь.
Это не моя основная причина всегда использовать is None
версия хотя. Я предпочитаю это, поскольку это более явно и тот факт, что or
возвращает один из его операндов не интуитивно для меня. Мне нравится забывать об этом так долго, как я могу;-) Дополнительная строка не проблема, это относительно редко.
Может быть, они не знают о втором? Я склонен использовать первое.
На самом деле есть разница. Второй позволит L = [], если вы передадите что-либо, что оценивается как Boolean false. 0 пустая строка или другие. Первый будет делать это только в том случае, если L не передан или был передан как None.