Почему пустой словарь является опасным значением по умолчанию в Python?

Я поставил dict в качестве значения по умолчанию для необязательного аргумента функции Python, и pylint (с использованием пакета Sublime) сказал мне, что это опасно. Может кто-нибудь объяснить, почему это так? И может ли вместо этого использовать None?


person tscizzle    schedule 12.10.2014    source источник
comment
Проблема с размещением пустого списка в качестве аргумента по умолчанию заключается в том, что он будет использоваться всеми вызовами функции - см. Важное предупреждение в docs.python.org/3/tutorial/   -  person hamed    schedule 18.01.2017


Ответы (2)


Это опасно, только если ваша функция изменит аргумент. Если вы измените аргумент по умолчанию, он будет сохраняться до следующего вызова, поэтому ваш «пустой» dict начнет содержать значения при вызовах, отличных от первого.

Да, использование None в таких случаях и безопасно, и общепринято.

person John Zwinck    schedule 12.10.2014
comment
если функция не изменяет аргумент, должны ли мы по-прежнему использовать None по умолчанию во имя передового опыта? - person NightFurry; 29.09.2017
comment
@NightFurry: Я не решаюсь прописывать здесь что-либо --_ 1_ часто лучший выбор, но, возможно, не в 100% случаев. Используйте свое суждение, но если вы не можете решить, None - беспроигрышный вариант. - person John Zwinck; 30.09.2017
comment
Если кто-то еще наткнется на этот вопрос, просмотрите этот ответ о дополнительных словарях в аргументах функций. Я считаю, что это гораздо лучшее обсуждение того, как следует решать эту проблему. По сути, сегодня нужно напечатать дополнительное отображение {key: value}. т.е. arg: Optional[Mapping[str, str]] = None - person Inarus Lynx; 19.01.2021
comment
Если функция не изменяет аргумент, но передает ссылку на него (возвращая ее, выдавая ее, вызывая какую-либо другую функцию с ней в качестве аргумента и т. Д.), То может возникнуть та же проблема. Я бы рекомендовал всегда использовать None, даже если функция написана тщательно, чтобы избежать таких ошибок, исключительно для того, чтобы кажущиеся безобидными изменения функции не могли ее сломать. - person kaya3; 28.03.2021

Давайте посмотрим на пример:

def f(value, key, hash={}):
    hash[value] = key
    return hash

print(f('a', 1))
print(f('b', 2))

Что вы, вероятно, ожидаете вывода:

{'a': 1}
{'b': 2}

Но на самом деле выводит:

{'a': 1}
{'a': 1, 'b': 2}
person Bill Lynch    schedule 12.10.2014
comment
Итак, как мы можем достичь значения по умолчанию, которое соответствует последующему коду, вместо того, чтобы сказать, если h равно None: h = {}, а затем продолжить код? - person Ricky Levi; 12.06.2019
comment
@RickyLevi, да. - person limeri; 09.09.2020
comment
Я немного опоздал, но хотел поблагодарить за этот пример. Я не знал об этом с Python, поэтому мне было интересно, почему пустой список / dict считается опасным. Это очень помогло. - person Mandemon; 20.10.2020
comment
так hash становится глобальной переменной? - person alper; 27.01.2021
comment
@alper это не глобальная переменная, вы можете получить к ней доступ только в рамках функции, но значение по умолчанию, если оно не указано, ссылается на dict, который вы определили как литерал. один из способов избежать этого - def func (hash = None): if hash == None: hash = {} ... - person marxus; 31.01.2021