> Как происходит передача аргументов в функцию в 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). Это означает:

  1. Параметр функции получает копию ссылки на объект, а не копию самого объекта.
  2. Если объект неизменяемый (immutable), любые операции внутри функции создают новый объект, и внешняя переменная продолжает указывать на старый.
  3. Если объект изменяемый (mutable), операции, модифицирующие объект на месте (например, list.append()), изменяют тот же объект, на который ссылается внешняя переменная.
  4. Присваивание параметру нового значения (param = something) внутри функции разрывает связь с внешней переменной - это локальное перенаправление имени.

Важно различать мутацию объекта и переназначение имени. Например, list.sort() мутирует объект, а list = sorted(list) создаёт новый объект и переназначает локальное имя.

На практике

Для senior-разработчика важно не только знать механику, но и уметь применять её в реальных сценариях:

  • При проектировании API функций нужно явно решать, будет ли функция мутировать входные данные или возвращать новый объект. Это влияет на предсказуемость кода.
  • Для защиты от нежелательной мутации можно передавать копии (list.copy(), copy.deepcopy()) или использовать неизменяемые структуры (tuple, frozenset).
  • Частая ошибка - использование изменяемых объектов как значений по умолчанию в параметрах. Это приводит к накоплению состояния между вызовами.
  • При работе с большими структурами данных передача по ссылке эффективна, так как не требует копирования.
  • В многопоточном или асинхронном коде мутация общих объектов через функции может привести к гонкам данных.

Пример кода

PYTHON
def modify_list(lst):
lst.append(4) # мутация - внешний список изменится
lst = [10, 20] # переназначение - внешний список не изменится
def modify_int(x):
x += 1 # создаётся новый объект int
return x
my_list = [1, 2, 3]
modify_list(my_list)
print(my_list) # [1, 2, 3, 4]
my_int = 5
modify_int(my_int)
print(my_int) # 5
# Опасный случай с default-аргументом
def add_item(item, container=[]):
container.append(item)
return container
print(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 внутри функции - это локальное переназначение, а не изменение объекта.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью