Как передаются аргументы в функцию — по значению или по ссылке?
- Передача параметров в Python по ссылке или по значению?
- Может ли функция изменить переданный ей список?
Ни то ни другое в классическом смысле: передаётся ссылка на объект (call by sharing).
- Изменяемый объект функция может поменять — изменение видно снаружи
- Переприсвоение параметра внутри функции снаружи не видно
А ещё Если менять аргумент не нужно — копируйте или возвращайте новый объект
Подробно
При вызове f(x) параметр функции становится ещё одним именем для того же объекта, на который указывает x. Объект не копируется.
Поэтому:
- если функция меняет объект (
lst.append(1),d["k"] = v), вызывающий код увидит изменение — это тот же объект; - если функция переприсваивает параметр (
lst = [1, 2]), она лишь привязывает своё локальное имя к новому объекту; снаружи ничего не меняется; - для неизменяемых объектов (числа, строки, кортежи) «изменить» можно только переприсваиванием, поэтому снаружи их не поменять никогда.
Это иногда называют «передача по значению ссылки» или call by sharing. В отличие от C++ ссылок, функция не может заставить внешнюю переменную указывать на другой объект.
Хорошая практика — не менять аргументы молча. Либо функция явно «изменяет на месте» (как list.sort, возвращает None), либо возвращает новый объект (как sorted).
Пример
def mutate(lst):
lst.append(99) # меняем объект
def rebind(lst):
lst = [0] # меняем только локальное имя
data = [1, 2]
mutate(data)
print(data) # [1, 2, 99]
rebind(data)
print(data) # [1, 2, 99] — не изменилосьЧто хотят услышать
- Передаётся ссылка на объект, копирования нет.
- Различие между изменением объекта и переприсвоением имени.
- Поведение для изменяемых и неизменяемых типов.
Частые ошибки
- Ответ «по ссылке» без оговорки про переприсвоение.
- Ответ «по значению, объект копируется».
Проверьте себя
Один верный вариант. Подумайте, потом откройте ответ.
Показать варианты и ответ
- ✓Передаётся ссылка на объект: изменение объекта видно снаружи, переприсвоение параметра — нет
- ✗Передача по ссылке, как в C++: присваивание параметру внутри функции меняет переменную вызывающего
- ✗Всегда передаётся копия объекта, поэтому снаружи ничего не меняется
- ✗Списки передаются по значению, числа — по ссылке
Что спросят дальше
Разбор темы
- Функции — аргументы, области видимости, замыкания и декораторы
Как передаются аргументы, *args и **kwargs, LEGB, ловушка изменяемого значения по умолчанию, замыкания и позднее связывание, декораторы и functools.
Связанные вопросы
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.