Python·100 вопросов

Почему опасно писать def f(x, arr=[])?

Ответ

Создание функций с изменяемыми значениями по умолчанию в сигнатуре является классической ловушкой для разработчиков на языке Python, с которой рано или поздно сталкивается каждый программист. Распространенной ошибкой является написание кода вида функции со списком по умолчанию, когда аргумент инициализируется пустым списком прямо при объявлении.

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

В результате этого архитектурного решения один и тот же созданный в памяти список становится общим для всех последующих вызовов функции, если вызывающий код явно не передает свой собственный аргумент. Это приводит к накоплению данных между вызовами, что может полностью сломать логику работы приложения и вызвать труднодиагностируемые ошибки.

Правильным и безопасным подходом является использование в качестве значения по умолчанию специального маркера None с последующей инициализацией внутри тела функции. Аналогичное правило безопасности распространяется и на другие изменяемые типы данных встроенной библиотеки Python, такие как словари и множества.

Избегайте использования списков, словарей и множеств в качестве значений по умолчанию в сигнатуре функции.
Установите значение аргумента по умолчанию равным None при объявлении функции.
Проверьте переданный аргумент внутри функции и инициализируйте новый контейнер, если аргумент равен None.
Используйте идиоматичную конструкцию вида arr = arr or list для краткой инициализации.
Проводите регулярный рефакторинг кода для выявления и устранения потенциальных проблем с изменяемыми аргументами.
Полезен ли этот ответ?

Другие вопросы этой темы

Связанные вопросы из других тем