При обычном запуске все три assert проходят. Каждый вызов меняет один общий default-список; во втором сравнении обе стороны ссылаются на него же, хотя вызовы последовательно добавляют элементы.
Как работает изменяемый параметр функции по умолчанию
При обычном запуске все три assert проходят. Каждый вызов меняет один общий default-список; во втором сравнении обе стороны ссылаются на него же, хотя вызовы последовательно добавляют элементы.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Продемонстрировать влияние изменяемого значения, указанного в качестве аргумента по умолчанию, на результат последующих вызовов функции. При каждом вызове без передачи собственного аргумента внутренний список будет сохранять добавленные элементы, что приводит к накоплению данных.
def add_one(lst=[]):
lst.append(1)
return lst
assert add_one() == [1]
assert add_one() == add_one()
assert add_one() == [1, 1, 1, 1]
Ответ
При обычном запуске все три assert проходят. Каждый вызов меняет один общий default-список; во втором сравнении обе стороны ссылаются на него же, хотя вызовы последовательно добавляют элементы.
После первого вызова список равен [1]. Во втором assert левый вызов делает [1, 1], правый — [1, 1, 1]. Левая сторона хранит не снимок, а ссылку на тот же объект, поэтому сравниваются одинаковые актуальные списки.
Последний вызов добавляет четвёртую единицу, и сравнение с [1, 1, 1, 1] тоже истинно. При Python -O assert удаляются вместе с находящимися внутри вызовами. Для независимых результатов используйте lst=None с созданием нового списка внутри функции.