None
в качестве значения по умолчанию и инициализировать изменяемый объект внутри функции.
Избегать использования изменяемых объектов (таких как списки, словари, множества) в значениях по умолчанию аргументов функций в Python - это важная рекомендация по нескольким причинам:
1. Ожидаемое поведение против фактического: Значения по умолчанию вычисляются только один раз, когда функция определяется, а не когда вызывается. Если изменяемый объект используется в качестве значения по умолчанию, он будет создан только один раз и будет использоваться всеми последующими вызовами функции, которые не передают явно аргумент для этого параметра. Это приводит к неожиданному поведению, когда изменения, внесенные в этот объект в одном вызове функции, сохраняются и влияют на последующие вызовы.
2. Сохранение состояния между вызовами: Поскольку один и тот же объект используется повторно, функция фактически сохраняет состояние между вызовами через этот изменяемый объект. Это может быть очень трудно отлаживать, так как поведение функции становится зависимым от предыдущих вызовов.
3. Неявное разделение данных: Если предполагается, что каждый вызов функции должен работать с новым, независимым экземпляром объекта, использование изменяемого значения по умолчанию нарушит это предположение. Все вызовы будут работать с одним и тем же объектом, что может привести к конфликтам и непредсказуемым результатам.
Пример:
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] (Ожидалось [2])
print(append_to_list(3)) # Вывод: [1, 2, 3] (Ожидалось [3])
Решение:
Вместо использования изменяемого объекта в качестве значения по умолчанию, используйте None
и создайте новый объект внутри функции, если значение аргумента не было передано:
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]
print(append_to_list(3)) # Вывод: [3]
Такой подход гарантирует, что каждый вызов функции получит новый, независимый список, если не будет предоставлен явный список в качестве аргумента.
В заключение: Избегайте изменяемых объектов в значениях по умолчанию, чтобы предотвратить неожиданное поведение, упростить отладку и гарантировать, что функция работает с независимыми данными при каждом вызове.