Когда мы говорим о Python и о том, что может вызвать у разработчиков слёзы (от радости или разочарования), обычно касаемся нескольких аспектов: сложности или странностей языка, проблем производительности или непонимания магии, которую иногда демонстрирует Python. Давайте рассмотрим пример кода, который может вызвать у друга-питониста сильные эмоции:
def add(x, items=[]):
items.append(x)
return items
print(add(1)) # Ожидается [1], получим [1]
print(add(2)) # Ожидается [2], получим [1, 2]... Почему?
def multiply(x, items=None):
if items is None:
items = []
items.append(x)
return items
print(multiply(1)) # Ожидается [1], получаем [1]
print(multiply(2)) # Ожидается [2], получаем [2], как и предполагается
Первый случай с функцией
add
показывает одну из частых "ловушек" Python, связанных с изменяемыми аргументами функций (в данном случае - списком). Новые Python-разработчики (и даже некоторые опытные) могут быть удивлены, обнаружив, что изменяемые аргументы инициализируются один раз и сохраняют свое состояние между вызовами функции, что приводит к неожиданным эффектам.
Второй случай с функцией
multiply
демонстрирует правильный способ использования изменяемых типов в качестве аргументов функций, чтобы избежать подобных "подводных камней".
Этот пример может вызвать у друга-питониста эмоции, так как он напоминает об особенностях Python, которые легко забываются, но которые могут привести к трудноуловимым багам в коде. Кроме того, он показывает, как важно глубоко понимать язык, на котором ты пишешь, чтобы создавать надёжные и предсказуемые программы.