Змінні — імена, посилання, ідентичність
Змінні — імена, посилання, ідентичність
Для чого потрібні змінні
У попередньому уроці значення існували лише всередині виклику: print(42) вивів число, і воно зникло. Щоб використати значення пізніше, його потрібно зберегти під іменем. Для цього існують змінні (variables). У Python змінна працює інакше, ніж у багатьох інших мовах, і саме цю різницю розбирає урок.
🎯 Мета лекції
- Пояснити, що змінна — це ім'я, яке вказує на об'єкт.
- Простежити виконання присвоєння та перепризначення.
- Розуміти, що
b = aстворює другу стрілку на той самий об'єкт. - Розрізняти
==(однакове значення) таis(той самий об'єкт). - Обмінювати значення двох змінних і давати змінним правильні імена.
🔑 Ключові терміни
- Ім'я (name): позначення в коді, яке вказує на об'єкт.
- Присвоєння (assignment): операція
ім'я = значення, яка прив'язує ім'я до об'єкта. - Простір імен (namespace): таблиця «ім'я → об'єкт».
- Посилання (reference): стрілка від імені до об'єкта.
- Лічильник посилань: кількість стрілок на об'єкт.
Пригадаємо попередній урок
id) і значення.float. Крапка робить число дробовим, навіть якщо дробова частина нульова.Змінна — це ім'я, а не коробка
У мові C змінна — це комірка пам'яті з адресою. Запис x = 5 кладе число 5 у цю комірку, а x = 7 замінить вміст на 7. Змінна й значення тут нероздільні.
У Python змінна — це ім'я (name), яке вказує на об'єкт. Значення лежить не в імені, а в об'єкті. Ім'я лише містить стрілку до нього. Тому x = 7 не замінює вміст: стрілка переходить на інший об'єкт.

Уявлення «змінна — коробка зі значенням» для Python неточне, і від нього залежить розуміння подальших тем: копіювання списків, аргументів функцій, змінюваних об'єктів. Тому цей урок використовує лише модель «ім'я → об'єкт».
Присвоєння крок за кроком
Запис x = 5 називається присвоєнням (assignment). Python виконує його у два кроки:
- Обчислює праву частину й отримує об'єкт (тут створює об'єкт
5). - Прив'язує (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:
- обчислює
count + 1і створює новий об'єкт100001; - переносить стрілку
countна новий об'єкт.
Старий об'єкт залишається в пам'яті, доки на нього вказує хоча б одна стрілка. Якщо стрілок не лишилось, Python його видаляє.
Змінна 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 потрібен для перевірки на 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 = 5 | SyntaxError: invalid decimal literal |
class = 1 | SyntaxError: invalid syntax |
user name = 1 | SyntaxError: invalid syntax |
my-var = 1 | SyntaxError: 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 вбудована функція стане недоступною в цій програмі.Підсумок
- Змінна в Python — це ім'я, яке вказує на об'єкт. Значення лежить в об'єкті, а не в імені.
- Присвоєння
x = значенняобчислює праву частину й прив'язує ім'я до об'єкта. x = x + 1для незмінних об'єктів створює новий об'єкт і переносить стрілку.b = aне копіює значення, а додає другу стрілку на той самий об'єкт.- Об'єкт без стрілок Python видаляє автоматично.
==порівнює значення,isперевіряє, чи це один об'єкт.a, b = b, aобмінює значення без допоміжної змінної.- Тип має об'єкт, а не ім'я.
Типові хибні уявлення
b = a обидва імені вказують на один об'єкт. Окремий об'єкт створює лише явне копіювання (тема уроку про списки).x переходить на нього.is перевіряє ідентичність, а не значення. Для чисел і рядків застосовуйте ==.int, потім на str.Передбачте, перш ніж запускати
a = 10
b = a
a = 20
print(a, b)
20 10
Після b = a обидва імені вказують на об'єкт 10. Рядок a = 20 переносить лише стрілку a, а b лишається на 10.
s = "a"
t = s
s = s + "b"
print(s, t)
ab a
Рядки незмінні. s + "b" створює новий рядок "ab", а t лишається на "a".
a, b, c = 1, 2, 3
a, b, c = c, a, b
print(a, b, c)
3 1 2
Права частина c, a, b обчислюється до присвоєння й дорівнює (3, 1, 2). Далі a = 3, b = 1, c = 2.
Практичні завдання
Заповніть таблицю значень a, b, c після кожного рядка без запуску коду, потім перевірте запуском:
a = 1
b = 2
c = a
a = b
b = c
print(a, b, c)
| Після рядка | a | b | c |
|---|---|---|---|
a = 1 | 1 | — | — |
b = 2 | 1 | 2 | — |
c = a | 1 | 2 | 1 |
a = b | 2 | 2 | 1 |
b = c | 2 | 1 | 1 |
2 1 1
Кожне ім'я неправильне. Напишіть коректну версію й поясніть чому:
2nd_place = "Олена"
my-score = 90
class = "A1"
total price = 150
second_place = "Олена"
my_score = 90
group = "A1"
total_price = 150
Ім'я не може починатися з цифри, містити дефіс чи пробіл, а class — ключове слово.
x = 1, y = 2, z = 3. Одним присвоєнням зробіть так, щоб x = 2, y = 3, z = 1.x, y, z = 1, 2, 3
x, y, z = y, z, x
print(x, y, z)
2 3 1
100000 так, щоб == давало True, а is — False. Поясніть результат.a = int("100000")
b = int("100000")
print(a == b, a is b)
True False
Значення однакові, але Python створив два окремі об'єкти. Число 100000 виходить за межі кешу малих цілих (−5…1024).
input(), int(), float() і форматування виводу.Об'єкти, значення і типи
Усе в Python є об'єктом із типом, ідентичністю та значенням. Літерали, типи int, float, str, bool і None, функції type та id, системи числення, цілі числа довільної точності та чому 0.1 + 0.2 не дорівнює 0.3.
Вирази, оператори, введення і перетворення типів
Арифметичні вирази та пріоритет операторів, ділення націло й остача з від'ємними числами, скорочені оператори, введення через input, перетворення типів int, float, str, bool та форматування виводу через f-рядки.