Изменение объектов по умолчанию
Анти-паттерн
При изменении объектов по умолчанию, использованных в качестве аргументов функции, поведение функции при повторных вызовах может быть неожиданным.
Пример¶
При попытке получить данные для переменной user_2_characteristics в переменной extra_user_fields будет лежать список ['age', 'work', 'age', 'work'].
Дело в том, что значения по умолчанию вычисляются только один раз, когда функция определяется, а не каждый раз, когда она вызывается. Таким образом, каждый вызов функции будет изменять значение по умолчанию для всех последующих вызовов.
Плохо:
def get_user_characteristics(user_id, extra_user_fields=[]):
default_user_fields = ['age', 'work']
extra_user_fields.extend(default_user_fields)
return extra_user_fields
user_1_characteristics = get_user_characteristics(1)
# ['age', 'work']
user_2_characteristics = get_user_characteristics(2)
# ['age', 'work', 'age', 'work']
user_3_characteristics = get_user_characteristics(3, ['phone'])
# ['phone', 'age', 'work']
user_4_characteristics = get_user_characteristics(4)
# ['age', 'work', 'age', 'work', 'age', 'work']
Хорошо:
def get_user_characteristics(user_id, extra_user_fields=None):
if extra_user_fields is None:
extra_user_fields = []
default_user_fields = ['age', 'work']
extra_user_fields.extend(default_user_fields)
return extra_user_fields
user_1_characteristics = get_user_characteristics(1)
# ['age', 'work']
user_2_characteristics = get_user_characteristics(2)
# ['age', 'work']
user_3_characteristics = get_user_characteristics(3, ['phone'])
# ['phone', 'age', 'work']
user_4_characteristics = get_user_characteristics(4)
# ['age', 'work']