Что происходит при передаче изменяемого объекта в функцию в Python

Ответ

В 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]