Главная страница » Python передача по ссылке

Python передача по ссылке

В Python нет строгой "передачи по ссылке" (pass by reference) в том смысле, как это понимается в языках вроде C++ или Java (где можно напрямую изменить переменную, переданную в функцию). Вместо этого, Python использует модель, которую часто называют "передачей по объекту" (pass by object reference) или "передачей по значению ссылки" (pass by assignment).

Чтобы лучше понять это, давайте разберем, как Python управляет переменными и объектами.

Объекты и переменные в Python

    В Python все является объектом. Переменные в Python не хранят значения напрямую; они хранят Ссылки (адреса) на объекты в памяти.

Представьте, что у вас есть ярлыки (переменные), которые указывают на коробки (объекты) с данными.

Python

X = 10 # x указывает на объект int со значением 10

My_list = [1, 2] # my_list указывает на объект list

Как работает "передача по объекту"

Когда вы передаете аргумент в функцию:

Создается новая локальная переменная внутри функции. Эта локальная переменная Получает копию ссылки на тот же объект, на который ссылается аргумент, переданный при вызове функции.

Вот что это означает на практике:

    Если объект Изменяемый (mutable): Вы можете изменить содержимое объекта внутри функции, и эти изменения будут видны вне функции, потому что обе переменные (внутри и снаружи функции) указывают на один и тот же объект. Примеры изменяемых объектов: list, dict, set, пользовательские объекты. Если объект Неизменяемый (immutable): Вы не можете изменить содержимое объекта. Если вы попытаетесь "изменить" его, Python создаст новый объект и заставит локальную переменную внутри функции указывать на него. Оригинальная переменная вне функции продолжит указывать на старый объект. Примеры неизменяемых объектов: int, float, str, tuple, bool, None.

Примеры

1. Передача изменяемого объекта (список)

Python

Def modify_list(lst_arg):

print(f"Внутри функции (начало): lst_arg = {lst_arg}, id = {id(lst_arg)}")

lst_arg. append(4) # Изменяем объект, на который ссылается lst_arg

print(f"Внутри функции (после append): lst_arg = {lst_arg}, id = {id(lst_arg)}")

# Присваиваем новый объект (это НЕ изменит original_list вне функции)

lst_arg = [10, 20, 30] # lst_arg теперь ссылается на НОВЫЙ объект

print(f"Внутри функции (после переприсваивания): lst_arg = {lst_arg}, id = {id(lst_arg)}")

Original_list = [1, 2, 3]

Print(f"Вне функции (начало): original_list = {original_list}, id = {id(original_list)}")

Modify_list(original_list)

Print(f"Вне функции (конец): original_list = {original_list}, id = {id(original_list)}")

Вывод:

Вне функции (начало): original_list = [1, 2, 3], id = <id_original_list>

Внутри функции (начало): lst_arg = [1, 2, 3], id = <id_original_list>

Внутри функции (после append): lst_arg = [1, 2, 3, 4], id = <id_original_list>

Внутри функции (после переприсваивания): lst_arg = [10, 20, 30], id = <id_new_list>

Вне функции (конец): original_list = [1, 2, 3, 4], id = <id_original_list>

Что произошло:

    Изначально original_list и lst_arg ссылались на один и тот же объект-список. lst_arg. append(4) Изменил сам объект-список, поэтому это изменение видно через original_list снаружи. lst_arg = [10, 20, 30] Заставило Lst_arg указывать на совершенно новый объект-список. Это не повлияло на original_list, который все еще указывал на оригинальный, но теперь измененный список [1, 2, 3, 4].

2. Передача неизменяемого объекта (число)

Python

Def modify_number(num_arg):

print(f"Внутри функции (начало): num_arg = {num_arg}, id = {id(num_arg)}")

num_arg += 10 # Создается НОВЫЙ объект int со значением (original_num + 10)

# num_arg теперь ссылается на этот новый объект

print(f"Внутри функции (после изменения): num_arg = {num_arg}, id = {id(num_arg)}")

Original_num = 5

Print(f"Вне функции (начало): original_num = {original_num}, id = {id(original_num)}")

Modify_number(original_num)

Print(f"Вне функции (конец): original_num = {original_num}, id = {id(original_num)}")

Вывод:

Вне функции (начало): original_num = 5, id = <id_object_5>

Внутри функции (начало): num_arg = 5, id = <id_object_5>

Внутри функции (после изменения): num_arg = 15, id = <id_object_15>

Вне функции (конец): original_num = 5, id = <id_object_5>

Что произошло:

    Изначально original_num и num_arg ссылались на один и тот же объект int со значением 5. num_arg += 10 не изменило объект 5. Поскольку целые числа неизменяемы, Python Создал новый объект Int со значением 15, и num_arg был переприсвоен, чтобы указывать на этот новый объект. original_num вне функции остался указывать на оригинальный объект 5.

Вывод

В Python нет прямой "передачи по ссылке" в том смысле, что вы не можете передать саму переменную (её "ячейку памяти") в функцию и изменить её там. Вы всегда передаете Копию ссылки на объект.

    Если объект, на который указывает ссылка, Изменяемый, вы можете модифицировать его содержимое, и эти изменения будут видны снаружи. Если объект, на который указывает ссылка, Неизменяемый, любая операция, которая кажется "изменением", на самом деле создает новый объект, и локальная переменная внутри функции будет ссылаться на этот новый объект, не затрагивая оригинальную переменную снаружи.

Понимание этой модели "передачи по объекту" является ключевым для предотвращения неожиданного поведения в ваших Python-программах.

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Прокрутить вверх