В Python параметры передаются по принципу 'call by object reference' (или 'call by sharing'). Это значит, что функция получает ссылку на объект, а не сам объект. Если объект изменяемый (mutable), то внутри функции можно менять его содержимое, и изменения отразятся на внешней переменной. Для неизменяемых объектов (immutable), например, числа или строки, изменение внутри функции создаёт новый объект, не затрагивая исходный.
Пример для изменяемого объекта:
def add_value(lst): lst.append(42) nums = [1, 2, 3] add_value(nums) print(nums) # [1, 2, 3, 42]
Для неизменяемого объекта:
def add_value(num): num += 10 x = 5 add_value(x) print(x) # 5
Вопрос: "Передаются ли в Python переменные в функции по ссылке или по значению?"
Ответ: Ни то, ни другое в классическом виде. Переменная передаёт именно ссылку на объект, но не саму переменную, и нельзя заменить сам объект для внешней переменной.
История В одном из проектов для парсинга данных функцию использовали для фильтрации списка. Новый список внутри функции не создавался, фильтрация производилась через изменения исходного списка. Это приводило к стиранию исходных данных — после нескольких запусков скрипта данных уже не было.
История Младший разработчик считал, что строки можно изменить "по ссылке" внутри функции, так как другие параметры (списки) удавалось изменять. В результате после вызова функции программа не получала ожидаемых изменений (строка не изменилась), что вызывало непонятные баги.
История В REST API для фильтрации входных данных разработчик забыл сделать копию словаря параметров, и при валидации значения "терялись" — параметры удалялись из исходного объекта, что ломало логику последующих запросов.