← Назад к вопросам

Как работают ссылки в Python?

1.0 Junior🔥 201 комментариев
#Python

Комментарии (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 — ОДНА И ТА ЖЕ ссылка

Практические рекомендации

  1. Для Immutable — не беспокойтесь, Python позаботится
  2. Для Mutable — думайте, хотите ли вы изменять исходный объект
  3. Всегда копируйте, если сомневаетесь — copy() для мелкой, deepcopy() для глубокой
  4. В pandas: используйте .copy() явно, чтобы избежать WarningError
  5. В NumPy: помните о views vs copies, особенно при нарезании массивов

Итого

Ссылки в Python — это указатели на объекты в памяти. Ключ — понимать разницу между mutable (изменяемыми) и immutable (неизменяемыми) типами. Изменяемые объекты могут быть случайно модифицированы через другие ссылки, поэтому нужно быть осторожным с копированием и передачей в функции.

Как работают ссылки в Python? | PrepBro