Проблема: Использование изменяемых значений (списки, словари) по умолчанию в аргументах функций может привести к неожиданному поведению, так как они создаются только один раз и используются совместно при каждом вызове функции.
Решение: Вместо присваивания изменяемого значения по умолчанию напрямую, используйте None
в качестве значения по умолчанию и создавайте изменяемый объект внутри функции, если аргумент равен None
.
Пример:
def my_function(my_list=None):
if my_list is None:
my_list = []
my_list.append("элемент")
return my_list
При передаче аргументов с изменяемыми значениями по умолчанию в функциях Python следует избегать прямого использования изменяемых объектов (таких как списки, словари) в качестве значений по умолчанию. Это связано с тем, что значение по умолчанию инициализируется только один раз, при определении функции, а не при каждом её вызове. Если изменяемое значение по умолчанию модифицируется внутри функции, это изменение будет сохранено и отразится на последующих вызовах функции. Это может привести к неожиданному и трудноотлаживаемому поведению.
Неправильно:
def append_to_list(value, my_list=[]):
my_list.append(value)
return my_list
print(append_to_list(1)) # Вывод: [1]
print(append_to_list(2)) # Вывод: [1, 2] (неожиданно!)
В примере выше, список my_list
инициализируется только один раз. При первом вызове он становится [1]
. При втором вызове, вместо создания нового пустого списка, используется существующий список [1]
, и к нему добавляется 2
.
Правильно:
def append_to_list(value, my_list=None):
if my_list is None:
my_list = []
my_list.append(value)
return my_list
print(append_to_list(1)) # Вывод: [1]
print(append_to_list(2)) # Вывод: [2] (ожидаемо)
В этом примере, в качестве значения по умолчанию используется None
. Внутри функции проверяется, равно ли my_list
значению None
. Если да, то создается новый пустой список. Таким образом, при каждом вызове функции, если my_list
не был передан явно, будет создаваться новый пустой список.
Краткое резюме:
None
в качестве значения по умолчанию.None
, и если да, то создавайте новый изменяемый объект.