Как исправить передачу по ссылке в Python?
Python: Передача по ссылке - Определение”Pass by Reference”
Перед тем, как мы углубимся в технические детали передачи по ссылке, полезно внимательнее изучить сам термин, разбив его на составные части:
- Передача означает предоставление аргумента функции.
- По ссылке означает, что аргумент, который вы передаете функции, является ссылкой на переменную, которая уже существует в памяти, а не независимой копией этой переменной.
Поскольку вы даете функции ссылку на существующую переменную, все операции, выполняемые с этой ссылкой, напрямую влияют на переменную, на которую она ссылается. Давайте рассмотрим некоторые примеры, чтобы увидеть, как это работает на практике.
Ниже вы увидите, как передать переменные по ссылке в C#. Обратите внимание на использование ключевого слова ref
в выделенных строках:
В этом примере создается метод MultiplyByTwo
, который принимает аргумент number
по ссылке с помощью ключевого слова ref
. Затем аргумент number
внутри метода умножается на 2, что приводит к изменению значения переменной arg
внутри метода Main
.
Еще одним интересным примером является использование ref
с типами, допускающими значения null
. Это показано в методе UpdateNullable
, который устанавливает значение nullableNumber
равным 10. После вызова этого метода значение nullableArg
в методе Main
также изменяется.
Но как эти понятия относятся к Python? Давайте рассмотрим, как Python обрабатывает передачу аргументов в функции.
Передача аргументов в Python
В Python аргументы передаются по значению по умолчанию. Это значит, что экземпляр аргумента, переданный в функцию, является независимой копией значения этого аргумента. Поступление такой копии значения аргумента позволяет функции работать с аргументом независимо от его исходного значения.
Например, рассмотрим следующий код:
В этом примере определена функция double
, которая принимает аргумент x
. Внутри функции значение x
умножается на 2. Однако, когда мы вызываем функцию double
и передаем в нее переменную num
, исходное значение num
(равное 10) остается неизменным.
В данном случае функция работает с копией значения num
, а не с самой переменной num
. Таким образом, функция не модифицирует исходную переменную.
Эта особенность языка Python немного отличается от того, как работают некоторые другие языки программирования, такие как C# или C++. Но существуют способы эмулировать передачу по ссылке в Python и достичь подобного поведения функций.
Воспроизведение передачи по ссылке с помощью Python
Хотя Python по умолчанию использует передачу по значению, есть несколько способов эмулировать передачу по ссылке и добиться того же поведения, что и в других языках программирования:
- Лучшая практика: возвращение и переустановка значения внутри функции.
- Лучшая практика: использование атрибутов объекта.
- Лучшая практика: использование словарей и списков.
Давайте рассмотрим каждый из этих подходов более подробно.
Лучшая практика: возвращение и переустановка значения
Первый способ эмулировать передачу по ссылке в Python - это возврат значения из функции и его переустановка в соответствующей переменной. Рассмотрим следующий пример:
В этом примере мы определяем функцию double
, которая принимает аргумент x
и возвращает его значение, умноженное на 2. Затем мы вызываем функцию double
и присваиваем возвращаемое значение переменной num
. В результате значение num
становится равным 20.
Путем возвращения значения из функции и его переустановки мы можем обойти ограничения передачи по значению и добиться изменения исходной переменной.
Лучшая практика: использование атрибутов объекта
Второй способ эмулировать передачу по ссылке в Python - это использование атрибутов объекта. Объекты в Python являются изменяемыми, что означает, что их значения могут быть изменены непосредственно. Рассмотрим следующий пример:
В этом примере мы определяем класс Number
, который имеет один атрибут num
. Затем мы определяем функцию double
, которая принимает аргумент number
и умножает его атрибут num
на 2. Затем мы создаем экземпляр класса Number
и вызываем функцию double
с этим экземпляром в качестве аргумента. Результатом будет изменение значения атрибута num
экземпляра класса Number
.
Используя атрибуты объекта, мы можем создать объект, который содержит переменную, и обновлять значение этой переменной непосредственно внутри функции.
Лучшая практика: использование словарей и списков
Третий способ эмулировать передачу по ссылке в Python - это использование словарей и списков. Словари и списки являются изменяемыми структурами данных в Python, что позволяет нам изменять их содержимое. Рассмотрим следующий пример:
В этом примере мы определяем функцию double
, которая принимает аргумент values
- список чисел. Затем мы проходим по списку с помощью цикла for
и умножаем каждый элемент на 2. После вызова функции double
значения в списке nums
обновляются.
Этот подход позволяет нам изменять значения внутри списка, а не копировать список и работать с копией значений.
Вывод
Хотя Python использовал передачу по значению, вам доступны несколько способов эмулировать передачу по ссылке и добиться схожего поведения функций. Путем возвращения и переустановки значений, использования атрибутов объекта и работы с изменяемыми структурами данных, такими как словари и списки, вы можете достичь желаемого поведения в Python.
Надеемся, что этот урок помог вам понять, как работает передача по ссылке в Python и как использовать несколько лучших практик, чтобы избежать проблем с аргументами функций.