Python Core

Змінні — імена, посилання, ідентичність

Змінна в Python — це ім'я, яке вказує на об'єкт у пам'яті, а не комірка зі значенням. Присвоєння, перепризначення, дві змінні на один об'єкт, лічильник посилань, різниця між is та ==, обмін значень і правила іменування.

Змінні — імена, посилання, ідентичність

Для чого потрібні змінні

У попередньому уроці значення існували лише всередині виклику: print(42) вивів число, і воно зникло. Щоб використати значення пізніше, його потрібно зберегти під іменем. Для цього існують змінні (variables). У Python змінна працює інакше, ніж у багатьох інших мовах, і саме цю різницю розбирає урок.

🎯 Мета лекції

  • Пояснити, що змінна — це ім'я, яке вказує на об'єкт.
  • Простежити виконання присвоєння та перепризначення.
  • Розуміти, що b = a створює другу стрілку на той самий об'єкт.
  • Розрізняти == (однакове значення) та is (той самий об'єкт).
  • Обмінювати значення двох змінних і давати змінним правильні імена.

🔑 Ключові терміни

  • Ім'я (name): позначення в коді, яке вказує на об'єкт.
  • Присвоєння (assignment): операція ім'я = значення, яка прив'язує ім'я до об'єкта.
  • Простір імен (namespace): таблиця «ім'я → об'єкт».
  • Посилання (reference): стрілка від імені до об'єкта.
  • Лічильник посилань: кількість стрілок на об'єкт.

Пригадаємо попередній урок

Змінна — це ім'я, а не коробка

У мові C змінна — це комірка пам'яті з адресою. Запис x = 5 кладе число 5 у цю комірку, а x = 7 замінить вміст на 7. Змінна й значення тут нероздільні.

У Python змінна — це ім'я (name), яке вказує на об'єкт. Значення лежить не в імені, а в об'єкті. Ім'я лише містить стрілку до нього. Тому x = 7 не замінює вміст: стрілка переходить на інший об'єкт.

Уявлення «змінна — коробка зі значенням» для Python неточне, і від нього залежить розуміння подальших тем: копіювання списків, аргументів функцій, змінюваних об'єктів. Тому цей урок використовує лише модель «ім'я → об'єкт».

Присвоєння крок за кроком

Запис x = 5 називається присвоєнням (assignment). Python виконує його у два кроки:

  1. Обчислює праву частину й отримує об'єкт (тут створює об'єкт 5).
  2. Прив'язує (binds) ліву частину: записує в таблицю імен, що x вказує на цей об'єкт.

Усі імена поточної програми зберігаються в просторі імен (namespace). Для коду на верхньому рівні його можна побачити функцією globals():

x = 5
y = x
print({k: v for k, v in globals().items() if not k.startswith("__")})
print(x is y, x == y, id(x) == id(y))
{'x': 5, 'y': 5}
True True True

Фільтр not k.startswith("__") прибирає службові імена, які Python створює сам. У словнику залишились лише x і y. Зверніть увагу на третій рядок: x і y вказують на той самий об'єкт, тому їхні id збігаються.

Простежте виконання в трасувальнику. Кнопка «вперед» (або клавіша →) виконує наступний рядок, а на помічених рядках Python спершу запитає, що станеться.

Імена та об'єкти
Завантаження трасування…

Після рядка y = x у пам'яті лежить один об'єкт 5, на який вказують дві стрілки. Присвоєння не копіює значення, а створює ще одну стрілку. Рядок x = 7 створює новий об'єкт 7 і переносить стрілку x, а y продовжує вказувати на 5.

Перепризначення: x = x + 1

Розглянемо типовий вираз count = count + 1. Він виглядає як збільшення числа, але числа в Python незмінні (immutable): об'єкт 100000 не можна змінити, можна створити інший. Тому Python:

  1. обчислює count + 1 і створює новий об'єкт 100001;
  2. переносить стрілку count на новий об'єкт.

Старий об'єкт залишається в пам'яті, доки на нього вказує хоча б одна стрілка. Якщо стрілок не лишилось, Python його видаляє.

count = count + 1
Завантаження трасування…

Змінна before у цьому прикладі зберігає id старого об'єкта. Це теж число: на схемі воно показано як окремий об'єкт int. Порівняння before == id(count) дає False, бо id змінився разом із об'єктом.

Фраза «змінна збільшилась» зручна, але неточна. Змінюється не об'єкт, а те, на що вказує ім'я. Для незмінних типів (int, float, str, bool) це завжди новий об'єкт.

Дві змінні на один об'єкт

Присвоєння b = a не копіює значення. Воно робить так, що b вказує на той самий об'єкт, що й a. Для незмінних об'єктів це безпечно: змінити їх неможливо, тому один об'єкт може мати скільки завгодно імен.

Кількість стрілок на об'єкт називають лічильником посилань (reference count). Python відстежує його й видаляє об'єкт, коли лічильник стає нульовим. Таке очищення пам'яті називається збиранням сміття (garbage collection).

Це пояснює, чому в Python не треба вручну звільняти пам'ять, як у C: об'єкт, який став недоступним, зникає автоматично.

is і ==

Два оператори порівняння відповідають на різні запитання:

ОператорПитанняЩо порівнює
==чи однакові значення?вміст об'єктів
isчи це один і той самий об'єкт?ідентичність (id)

Список зручний для демонстрації, бо два різні списки можуть мати однаковий вміст. (Докладно про списки йдеться в одному з наступних уроків; тут їх використано лише для порівняння.)

a = [1, 2]
b = a
c = [1, 2]
print(a == b, a is b)
print(a == c, a is c)
True True
True False

Список c має те саме значення, що й a, але це окремий об'єкт. Перевірте це в трасувальнику: після c = [1, 2] на схемі з'являється другий список.

is і ==
Завантаження трасування…

Для порівняння значень майже завжди використовують ==. Оператор is потрібен для перевірки на None: if x is None.

Кеш малих цілих чисел

Python заздалегідь створює об'єкти для малих цілих чисел (у версії 3.15 це діапазон від -5 до 1024) і використовує їх повторно:

a = int("1000"); b = int("1000")
print(a is b, a == b)
c = int("100000"); d = int("100000")
print(c is d, c == d)
True True
False True

Для 1000 обидва імені вказують на один об'єкт, а для 100000 об'єкти різні. Це деталь реалізації CPython, яка залежить від версії. Не покладайтеся на неї й не використовуйте is для порівняння чисел.

Множинне присвоєння та обмін значень

Python дозволяє присвоїти кілька імен одним рядком:

p = q = 0
a, b = 1, 2
first, *rest = [1, 2, 3]
print(p, q, p is q)
print(a, b)
print(first, rest)
0 0 True
1 2
1 [2, 3]
  • p = q = 0 — обидва імені вказують на один об'єкт 0.
  • a, b = 1, 2 — значення розподіляються за позицією.
  • first, *rest = ... — перше значення в first, решта в rest (про * докладніше в уроці про списки).

Запис a, b = b, a міняє значення місцями без допоміжної змінної. Права частина b, a спершу повністю обчислюється (створюється пара посилань на об'єкти), і лише потім імена прив'язуються заново. Тому жодне значення не губиться:

a, b = 1, 2
a, b = b, a
print(a, b)
2 1
Обмін значень
Завантаження трасування…

Типи належать об'єктам, а не іменам

Тип має об'єкт, а ім'я може вказувати на об'єкт будь-якого типу. Тому одне ім'я може в різні моменти вказувати на значення різних типів. Така властивість називається динамічною типізацією (dynamic typing):

x = 5
print(type(x))
x = "текст"
print(type(x))
<class 'int'>
<class 'str'>

Помилка виникає не під час присвоєння, а коли об'єкт не підтримує операцію:

x = 5
x.append(1)
AttributeError: 'int' object has no attribute 'append'

Правила іменування

Ім'я змінної має такі правила:

  • складається з літер, цифр і символу підкреслення _;
  • не починається з цифри;
  • розрізняє великі й малі літери (name і Name — різні імена);
  • не збігається з ключовим словом Python (у версії 3.15 їх 35: if, for, class, None, True тощо).

Типові помилки та повідомлення Python:

КодПовідомлення
1x = 5SyntaxError: invalid decimal literal
class = 1SyntaxError: invalid syntax
user name = 1SyntaxError: invalid syntax
my-var = 1SyntaxError: cannot assign to expression here. Maybe you meant '==' instead of '='?
print(Name) після name = "a"NameError: name 'Name' is not defined. Did you mean: 'name'?

Дефіс у my-var Python читає як віднімання, звідси незвичне повідомлення.

Крім обов'язкових правил діє угода PEP 8 — офіційний стиль коду Python:

  • імена змінних пишуть малими літерами зі знаком підкреслення: user_name, total_price (стиль snake_case);
  • імена-константи, значення яких не змінюється, пишуть великими: MAX_SIZE;
  • ім'я має описувати зміст: age краще за a, total_price краще за tp.
Перевірити, чи слово зарезервоване, можна через import keyword і keyword.iskeyword("class"). Ім'я print не є ключовим словом, але його не слід перепризначати: після print = 5 вбудована функція стане недоступною в цій програмі.

Підсумок

  1. Змінна в Python — це ім'я, яке вказує на об'єкт. Значення лежить в об'єкті, а не в імені.
  2. Присвоєння x = значення обчислює праву частину й прив'язує ім'я до об'єкта.
  3. x = x + 1 для незмінних об'єктів створює новий об'єкт і переносить стрілку.
  4. b = a не копіює значення, а додає другу стрілку на той самий об'єкт.
  5. Об'єкт без стрілок Python видаляє автоматично.
  6. == порівнює значення, is перевіряє, чи це один об'єкт.
  7. a, b = b, a обмінює значення без допоміжної змінної.
  8. Тип має об'єкт, а не ім'я.

Типові хибні уявлення

Передбачте, перш ніж запускати

Практичні завдання

Наступний урок: вирази, оператори, введення та перетворення типів. Арифметика, input(), int(), float() і форматування виводу.
Copyright © 2026