Введение
В этом практическом занятии мы рассмотрим основы присвоения и ссылок в Python. Мы изучим, как Python обрабатывает присвоения, как создавать ссылки и как работать с изменяемыми и неизменяемыми объектами.
Введение в присвоения в Python
В Python присвоение - это процесс связывания имени с объектом. Статements присвоения имеют следующий общий вид:
variable = expression
Выражение справа от знака равно вычисляется, и его значение присваивается переменной слева от знака равно.
Посмотрим на простой пример:
Простой тест
Откройте Терминал и введите в терминале следующую команду.
python3
Затем введите следующий код.
## Присвойте значение 42 переменной 'x' и выведите его.
x = 42
print(x)
Результат:
42
Здесь мы присваиваем переменной x значение 42 с помощью оператора =. Затем мы выводим значение x.
Понимание ссылок
В Python переменные - это ссылки на объекты. Когда вы присваиваете значение переменной, вы фактически создаете ссылку на объект, представляющий это значение.
Вот пример, иллюстрирующий этот концепт:
## Демонстрирует ссылки в Python.
x = [1, 2, 3]
y = x
y.append(4)
print("x:", x)
print("y:", y)
Результат:
x: [1, 2, 3, 4]
y: [1, 2, 3, 4]
В этом примере как x, так и y ссылаются на один и тот же объект списка. Когда мы изменяем список по ссылке y, добавляя 4, изменения отражаются и в x, и в y.
Изменяемые и неизменяемые объекты
В Python есть два типа объектов: изменяемые и неизменяемые.
Изменяемые объекты могут быть изменены после их создания. Списки, словари и множества - это примеры изменяемых объектов.
Неизменяемые объекты не могут быть изменены после их создания. Целые числа, числа с плавающей точкой, строки и кортежи - это примеры неизменяемых объектов.
Посмотрим на пример, демонстрирующий разницу между изменяемыми и неизменяемыми объектами:
## Пример изменяемого объекта
mutable_list = [1, 2, 3]
another_mutable_list = mutable_list
another_mutable_list.append(4)
print("mutable_list:", mutable_list)
Результат:
mutable_list: [1, 2, 3, 4]
mutable_list добавляет 4 в конец списка, потому что это изменяемый объект, но неизменяемые объекты не могут быть изменены после их создания.
## Пример неизменяемого объекта
immutable_string = "hello"
another_immutable_string = immutable_string
another_immutable_string = another_immutable_string.upper()
print("immutable_string:", immutable_string)
Результат:
immutable_string: hello
Ничего не меняется, и если мы хотим изменить immutable_string следующим образом, Python-интерпретатор вызовет ошибку TypeError:
immutable_string[0] = '1'
Результат:
TypeError: 'str' object does not support item assignment
Примеры
Посмотрим на несколько более примеров, чтобы укрепить концепции, которые мы выучили:
Пример 1: Функция с изменяемым аргументом по умолчанию
Избегайте использования изменяемых объектов в качестве аргументов по умолчанию в функциях:
def bad_append(new_item, a_list=[]):
a_list.append(new_item)
return a_list
print(bad_append('one'))
Результат:
['one']
Похоже, все в порядке, но если мы вызовем эту функцию снова:
print(bad_append('two'))
Результат:
['one', 'two']
Проблема здесь заключается в том, что значение по умолчанию a_list вычисляется при определении функции. Поэтому каждый раз, когда вы вызываете функцию, вы получаете одно и то же значение по умолчанию. Правильным способом является создание его во время выполнения внутри функции.
def append_to_list(item: int, a_list: list = None) -> list:
"""Добавляет элемент в список и возвращает обновленный список."""
if a_list is None:
a_list = []
a_list.append(item)
return a_list
list_a = append_to_list(1, [1, 2, 3])
print(list_a)
Результат:
[1, 2, 3, 1]
Пример 2: Копирование изменяемых объектов
Используйте модуль copy, чтобы создать новый объект, когда вы хотите работать с копией изменяемого объекта:
import copy
## Демонстрирует использование модуля copy.
original_list = [1, 2, 3]
copied_list = copy.copy(original_list)
copied_list.append(4)
print("original_list:", original_list)
print("copied_list:", copied_list)
Результат:
original_list: [1, 2, 3]
copied_list: [1, 2, 3, 4]
В этом примере copied_list - это новый объект, являющийся копией original_list. Когда мы добавляем 4 в copied_list, original_list остается неизменным.
Пример 3: Глубокое копирование изменяемых объектов
Для вложенных изменяемых объектов использование функции copy не работает:
## ваш пример с копированием здесь
original_nested_list = [[1, 2], [3, 4]]
copied_nested_list = copy.copy(original_nested_list)
copied_nested_list[0].append(5)
print("original_nested_list:", original_nested_list)
print("copied_nested_list:", copied_nested_list)
Результат:
original_nested_list: [[1, 2, 5], [3, 4]]
copied_nested_list: [[1, 2, 5], [3, 4]]
Мы видим, что когда мы добавляем 5 в copied_nested_list, original_nested_list также добавляет 5. Поэтому вы должны использовать функцию deepcopy вместо этого:
## ваш пример с deepcopy здесь
original_nested_list = [[1, 2], [3, 4]]
deep_copied_list = copy.deepcopy(original_nested_list)
deep_copied_list[0].append(5)
print("original_nested_list:", original_nested_list)
print("deep_copied_list:", deep_copied_list)
Результат:
original_nested_list: [[1, 2], [3, 4]]
deep_copied_list: [[1, 2, 5], [3, 4]]
В этом примере функция deepcopy рекурсивно копирует original_nested_list, в то время как функция copy создает ссылку на первый уровень данных original_nested_list.
Резюме
В этом руководстве по программированию на Python мы рассмотрели основы присвоения и ссылок в Python. Мы изучили, как Python обрабатывает присвоения, как создавать ссылки и как работать с изменяемыми и неизменяемыми объектами. Разбирая эти концепции, вы будете в лучшем состоянии для написания эффективного и правильного кода на Python.



