Как правильно передавать аргументы с изменяемыми значениями по умолчанию через функции?

Проблема: Использование изменяемых значений (списки, словари) по умолчанию в аргументах функций может привести к неожиданному поведению, так как они создаются только один раз и используются совместно при каждом вызове функции.

Решение: Вместо присваивания изменяемого значения по умолчанию напрямую, используйте 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, и если да, то создавайте новый изменяемый объект.

0