Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI29 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Как работают ссылки в Python?
Введение в Python references
В Python всё является объектом, и переменные — это не контейнеры со значениями, а ссылки на объекты в памяти. Это фундаментальное отличие от языков вроде C, где переменные содержат значения напрямую.
Основные концепции
1. Переменная как ссылка на объект
a = 5
print(id(a)) # Выведет адрес в памяти объекта
b = 5
print(id(b)) # Может быть той же адресу (для малых чисел Python кэширует)
print(a is b) # True (для чисел -5...256 из-за кэширования)
2. Mutable vs Immutable (Изменяемые vs Неизменяемые)
# IMMUTABLE (неизменяемые)
# int, float, str, tuple, frozenset, bool, bytes, None
a = "hello"
b = a
b = "world" # Создается НОВЫЙ объект, 'b' теперь ссылается на него
print(a) # "hello" — не изменилось
print(b) # "world"
# MUTABLE (изменяемые)
# list, dict, set, bytearray
a = [1, 2, 3]
b = a # 'b' и 'a' ссылаются на ОДИН И ТОТ ЖЕ объект
b.append(4)
print(a) # [1, 2, 3, 4] — ИЗМЕНИЛОСЬ!
print(b) # [1, 2, 3, 4]
print(a is b) # True — один и тот же объект
Копирование объектов
# МЕЛКОЕ копирование (Shallow copy)
original = [1, 2, [3, 4]]
shallow = original.copy() # или list(original)
shallow[0] = 99
print(original) # [1, 2, [3, 4]] — первый элемент не изменился
shallow[2].append(5)
print(original) # [1, 2, [3, 4, 5]] — вложенный список ИЗМЕНИЛСЯ!
# ГЛУБОКОЕ копирование (Deep copy)
import copy
original = [1, 2, [3, 4]]
deep = copy.deepcopy(original)
deep[2].append(5)
print(original) # [1, 2, [3, 4]] — ничего не изменилось!
Передача аргументов в функции
# Для IMMUTABLE типов (int, str, tuple)
def modify_immutable(x):
x = x + 1 # Создается НОВЫЙ объект
return x
a = 5
result = modify_immutable(a)
print(a) # 5 — не изменилось
# Для MUTABLE типов (list, dict)
def modify_mutable(lst):
lst.append(999) # Изменяем объект "на месте"
my_list = [1, 2, 3]
modify_mutable(my_list)
print(my_list) # [1, 2, 3, 999] — ИЗМЕНИЛОСЬ!
Важные примеры для Data Science
Проблема с mutable defaults:
# ПЛОХО
def append_to_list(item, my_list=[]):
my_list.append(item)
return my_list
print(append_to_list(1)) # [1]
print(append_to_list(2)) # [1, 2] — ВСЕ ЕЩЕ ЕСТЬ 1!
# ХОРОШО
def append_to_list(item, my_list=None):
if my_list is None:
my_list = []
my_list.append(item)
return my_list
Работа с DataFrame и Series
import pandas as pd
df = pd.DataFrame({'A': [1, 2, 3]})
df_ref = df # df_ref — это ссылка на ТОТ ЖЕ DataFrame
df_ref.loc[0, 'A'] = 999
print(df) # Изменился! [999, 2, 3]
# Для копирования DataFrame
df_copy = df.copy() # Мелкая копия
df_deep = df.copy(deep=True) # Глубокая копия
# Или для Series
s = pd.Series([1, 2, 3])
s_copy = s.copy() # Явная копия
NumPy arrays
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
view = arr[1:3] # Это ВИД (view), ссылка на часть
view[0] = 999
print(arr) # [1, 999, 3, 4, 5] — ИЗМЕНИЛСЯ!
# Явная копия
copy_arr = arr[1:3].copy()
copy_arr[0] = 999
print(arr) # [1, 2, 3, 4, 5] — не изменился
Счетчик ссылок (Reference Counting)
Python использует подсчет ссылок для управления памятью:
import sys
a = []
print(sys.getrefcount(a)) # Количество ссылок на объект
b = a # Добавляем ссылку
print(sys.getrefcount(a)) # Увеличилось на 1
c = a
print(sys.getrefcount(a)) # Увеличилось еще на 1
del b # Удаляем ссылку
print(sys.getrefcount(a)) # Уменьшилось на 1
Идентичность vs Равенство
a = [1, 2, 3]
b = [1, 2, 3]
print(a == b) # True — ЗНАЧЕНИЯ одинаковые
print(a is b) # False — РАЗНЫЕ объекты в памяти
c = a
print(c is a) # True — ОДНА И ТА ЖЕ ссылка
Практические рекомендации
- Для Immutable — не беспокойтесь, Python позаботится
- Для Mutable — думайте, хотите ли вы изменять исходный объект
- Всегда копируйте, если сомневаетесь — copy() для мелкой, deepcopy() для глубокой
- В pandas: используйте .copy() явно, чтобы избежать WarningError
- В NumPy: помните о views vs copies, особенно при нарезании массивов
Итого
Ссылки в Python — это указатели на объекты в памяти. Ключ — понимать разницу между mutable (изменяемыми) и immutable (неизменяемыми) типами. Изменяемые объекты могут быть случайно модифицированы через другие ссылки, поэтому нужно быть осторожным с копированием и передачей в функции.