Ответ
В Python аргументы передаются "по присваиванию" (pass-by-assignment), что для изменяемых типов данных (таких как list
, dict
, set
) означает передачу ссылки на сам объект.
Это значит, что любые изменения, произведенные с объектом внутри функции, будут видны и за её пределами, поскольку и внешняя, и внутренняя переменные указывают на одну и ту же область памяти.
Пример: изменение исходного объекта
# Функция добавляет элемент в переданный список
def add_to_list(items: list):
print(f" ID объекта внутри функции: {id(items)}")
items.append(4)
my_list = [1, 2, 3]
print(f"ID объекта до вызова: {id(my_list)}")
add_to_list(my_list)
print(f"Список после вызова функции: {my_list}") # Вывод: [1, 2, 3, 4]
Как избежать нежелательных изменений
Чтобы избежать изменения (мутации) оригинального объекта, необходимо работать с его копией. Для этого можно использовать метод .copy()
или срезы [:]
.
# Функция работает с копией списка
def safe_add_to_list(items: list) -> list:
local_list = items.copy() # Создаем поверхностную копию
local_list.append(4)
return local_list
my_list = [1, 2, 3]
new_list = safe_add_to_list(my_list)
print(f"Оригинальный список: {my_list}") # Вывод: [1, 2, 3]
print(f"Новый список: {new_list}") # Вывод: [1, 2, 3, 4]