> Как происходит передача аргументов в функцию в Python (Python)
Уровень: senior · Роль: backend · Язык: Python · Категория: Технические вопросы
Компании: IPChain, Фабрика решений
Стек: Python
> Пример ответа
Короткий ответ
В Python аргументы передаются по ссылке, но с учётом неизменяемости объектов. Это называют "передача объекта по ссылке" или call-by-object-reference. Примитивные типы (int, str, tuple) неизменяемы, поэтому их изменение внутри функции не влияет на внешнюю переменную. Изменяемые объекты (list, dict, set) передаются по ссылке, и их мутация видна снаружи. При этом присваивание нового значения параметру внутри функции не меняет внешнюю переменную.
Подробное объяснение
Механика передачи аргументов в Python основана на модели объектов и ссылок. Каждая переменная - это имя, указывающее на объект в памяти. При вызове функции создаются новые имена (параметры), которые связываются с теми же объектами, что и аргументы вызывающего кода.
Ключевой момент: в Python нет ни передачи по значению (как в C для примитивов), ни передачи по ссылке (как в C++ с &). Вместо этого работает семантика "передача объекта по ссылке" (pass-by-object-reference) или "передача по значению ссылки" (pass-by-reference-value). Это означает:
- Параметр функции получает копию ссылки на объект, а не копию самого объекта.
- Если объект неизменяемый (immutable), любые операции внутри функции создают новый объект, и внешняя переменная продолжает указывать на старый.
- Если объект изменяемый (mutable), операции, модифицирующие объект на месте (например,
list.append()), изменяют тот же объект, на который ссылается внешняя переменная. - Присваивание параметру нового значения (
param = something) внутри функции разрывает связь с внешней переменной - это локальное перенаправление имени.
Важно различать мутацию объекта и переназначение имени. Например, list.sort() мутирует объект, а list = sorted(list) создаёт новый объект и переназначает локальное имя.
На практике
Для senior-разработчика важно не только знать механику, но и уметь применять её в реальных сценариях:
- При проектировании API функций нужно явно решать, будет ли функция мутировать входные данные или возвращать новый объект. Это влияет на предсказуемость кода.
- Для защиты от нежелательной мутации можно передавать копии (
list.copy(),copy.deepcopy()) или использовать неизменяемые структуры (tuple,frozenset). - Частая ошибка - использование изменяемых объектов как значений по умолчанию в параметрах. Это приводит к накоплению состояния между вызовами.
- При работе с большими структурами данных передача по ссылке эффективна, так как не требует копирования.
- В многопоточном или асинхронном коде мутация общих объектов через функции может привести к гонкам данных.
Пример кода
PYTHONdef modify_list(lst):lst.append(4) # мутация - внешний список изменитсяlst = [10, 20] # переназначение - внешний список не изменитсяdef modify_int(x):x += 1 # создаётся новый объект intreturn xmy_list = [1, 2, 3]modify_list(my_list)print(my_list) # [1, 2, 3, 4]my_int = 5modify_int(my_int)print(my_int) # 5# Опасный случай с default-аргументомdef add_item(item, container=[]):container.append(item)return containerprint(add_item(1)) # [1]print(add_item(2)) # [1, 2] - неожиданно!
Как отвечать на собеседовании
Начните с чёткого тезиса: "в Python аргументы передаются по ссылке на объект, но с учётом неизменяемости". Затем объясните разницу между мутацией и переназначением. Приведите пример с list и int. Обязательно упомяните проблему изменяемых default-аргументов - это классический вопрос для senior.
Покажите глубину: расскажите про внутреннее устройство - переменные как имена в пространстве имён, объекты в куче, ссылки как указатели. Упомяните, что это поведение одинаково для всех типов, просто неизменяемые типы не предоставляют методов мутации.
Если спросят про производительность - отметьте, что передача по ссылке избегает копирования, но мутация общих объектов требует осторожности. Можно упомянуть copy и deepcopy для защиты.
Завершите практическим советом: всегда документируйте, мутирует ли функция входные данные, и избегайте изменяемых default-аргументов.
Что проверяет интервьюер
Интервьюер оценивает:
- Понимание модели памяти Python: объекты, ссылки, имена.
- Умение различать мутацию и переназначение.
- Знание особенностей неизменяемых и изменяемых типов.
- Осведомлённость о типичных подводных камнях (default-аргументы, случайная мутация).
- Способность объяснить сложную тему простыми словами и с примерами.
- Практическое мышление: как это влияет на проектирование API и обработку данных.
Для senior-уровня важно показать не только знание фактов, но и понимание последствий для архитектуры кода, потокобезопасности и производительности.
Типичные ошибки
- Утверждение "в Python передача по значению" - неверно для изменяемых объектов.
- Утверждение "в Python передача по ссылке" - неверно, так как переназначение параметра не влияет на внешнюю переменную.
- Путаница между
list.sort()(мутация) иsorted(list)(новый объект). - Использование изменяемых объектов как значений по умолчанию - классическая ошибка.
- Предположение, что
x += 1для int изменит внешнюю переменную - неверно, создаётся новый объект. - Игнорирование необходимости копирования при передаче изменяемых объектов в функции, которые могут их мутировать.
- Непонимание, что
param = valueвнутри функции - это локальное переназначение, а не изменение объекта.
> Похожие задачи по Python
Как устроены структуры данных list, dict и set в Python?
Какие HTTP статусы существуют и каково назначение 2xx, 3xx, 4xx, 5xx
Что такое coroutine и как он работает в Python
В каком порядке строить составной индекс для user_id и даты
> Похожие задачи по backend
Как устроены структуры данных list, dict и set в Python?
Какие HTTP статусы существуют и каково назначение 2xx, 3xx, 4xx, 5xx
В чем разница между процессом и потоком и какова их иерархия?
Что такое coroutine и как он работает в Python
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью