Перейти до змісту

Типи даних


📌 Змінні та незмінні типи


У Python більшість вбудованих типів є незмінними (immutable). До незмінних відносяться числові типи (int, float, complex), а також bool (похідний від int), str (рядок), bytes, tuple і frozenset . Незмінний об’єкт не можна змінити після створення; наприклад, цілочисельні чи рядкові значення перепризначаються як нові об’єкти.

Натомість змінні типи дозволяють змінювати свій вміст у місці. До них належать list, dict (словник) і set (множина). Наприклад, list і dict підтримують методи, що додають/видаляють елементи на місці, не створюючи нового об’єкта.


📌 NoneType (None)


  • Опис: None – єдиний екземпляр типу NoneType. Використовується для позначення відсутності значення (наприклад, коли функція нічого не повернула). Цей об’єкт не підтримує жодних операцій над своїм вмістом.
  • Змінюваність: незмінний (singelton). Єдиний екземпляр – об’єкт None. Вираз type(None)() повертає те саме None.
  • Стандартні функції - для None застосовні тільки базові:
    • type(None)
    • isinstance(obj, type(None))
    • bool(None) повертає False. None також є false-подібним значенням у булевому контексті.
  • Методи: Власних методів у None нема.

📌 Числові типи даних


➡️ int

Цілочисельний тип даних

  • Опис: Тип int призначений для цілих чисел довільної точності. Цілі числа незмінні (immutable) – їх значення не може бути змінено після створення.
  • Змінюваність: незмінний.
  • Стандартні функції: можна застосовувати загальні вбудовані функції, наприклад
    • type(x)
    • isinstance(x, int)
    • abs(x)
    • pow(x, y) та функцію перетворення int(x). (Наприклад, int("123") повертає 123.)
  • Методи: У int є додаткові методи для роботи з двійковим представленням і статистикою бітів, такі як:
    • x.bit_length() – число бітів у двійковому представленні без знаку
    • x.bit_count() – кількість одиниць у двійковому представленні (популяційний обчислювач)
    • x.to_bytes(length, byteorder, , signed) – перетворює ціле число в байти; і відповідний клас-метод int.from_bytes(bytes, byteorder, , signed).
    • Інші методи, отримані від абстрактних базових класів, забезпечують операції порівняння, арифметику (+, -, *, // тощо) і бітові операції (&, |, ^, <<, >>, ~).

➡️ float

Числовий тип із плаваючою крапкою

  • Опис: Тип float представляє числа з плаваючою крапкою (двійкові float за стандартом IEEE754). Це також незмінний (immutable) тип.
  • Змінюваність: незмінний.
  • Стандартні функції:
    • Загальні вбудовані:
      • type(x)
      • isinstance(x, float)
      • abs(x)
      • round(x, n) тощо,
    • перетворення
      • float(x). Наприклад, float("3.14") поверне 3.14.
  • Методи: Для float доступні методи:
    • x.as_integer_ratio() – пару цілих чисел (p, q), що дорівнюють r = p/q (для представлення числа як дробу)
    • x.is_integer() – повертає True, якщо число дійсне але цілочисельне (наприклад, 2.0), інакше False
    • x.hex() і клас-метод float.fromhex(s) – перетворюють число в шестнадцятковий формат і назад (точне відображення)

Для перетворень також працюють int(x) (округлює до цілого) і str(x).


📌 Булевий тип (bool)


  • Опис: Тип bool представляє булеві значення True і False. Має лише два екземпляри – True (1) і False (0). bool є підкласом int, тому чисельно True == 1, False == 0, але рекомендується не покладатися на це і явно конвертувати через int().
  • Змінюваність: незмінний.
  • Стандартні функції:
    • type(x)
    • isinstance(x, bool)
    • bool(x) – функція перетворення до булевого (bool("") дає False, bool(5) дає True тощо).
  • Операції: Логічні операції задаються and, or, not. Також можна застосовувати побітові &, |, ^, але вони працюють як логічні для булевих.
  • Методи: Окрім стандартних методів від int (якщо потреба), власних методів bool не має.

📌 Рядковий тип (str)


  • Опис: str – послідовність символів Unicode (текстовий тип). Рядки є незмінними (immutable) послідовностями символів. У Python немає окремого “символьного” типу; кожен символ – це рядок довжиною 1.
  • Змінюваність: незмінний. Для ефективної побудови рядків використовують методи типу str.join() або io.StringIO замість послідовного додавання.
  • Стандартні функції:
    • len(s)
    • type(s)
    • isinstance(s, str)
    • sorted(s) (поверне список символів у відсортованому порядку)
    • str(x) (конвертація будь-якого об’єкта в рядок)
  • Методи: str має багато методів для обробки тексту. Основні з них:
    • Робота з випадком: s.lower(), s.upper(), s.title(), s.capitalize(), s.casefold().
    • Пошук і заміна: s.find(sub), s.index(sub), s.count(sub), s.replace(old, new), s.startswith(prefix), s.endswith(suffix).
    • Розбивання і з’єднання: s.split(sep), s.rsplit(sep), s.strip(chars), s.rstrip(chars), s.lstrip(chars), sep.join(iterable) (де sep – рядок).
    • Форматування: s.format(...) (див. нижче) та «старий» оператор %.
    • Інші: s.center(width), s.count(), s.encode(), s.replace(), s.format(), s.split(), s.strip(), s.join(), тощо (повний перелік – в документації).

➡️Форматування рядків

Python підтримує кілька способів форматувати рядки:

  • Оператор % (старий стиль, «printf-форматування»): Використовується format_string % values. Форматні специфікатори (%s, %d, %f тощо) у рядку замінюються елементами values (кортеж або словник). Наприклад:
'%s має %d яблук' % ('Юля', 5) 

дасть "Юля має 5 яблук". Цей спосіб корениться в C-функції sprintf().


print('Superhero name is %s, his super power - %s, his enemy - %s' % (name, super_power, enemy))
  • Метод str.format(): У форматному рядку {} позначають місце вставки. Наприклад, "{} має {} яблук".format('Юля', 5) або "{name} має {count} яблук".format(name='Юля', count=5). Цей підхід гнучкіший і допускає розширені форматні специфікатори. Його синтаксис детально описано в документації (PEP 3101).
print('Superhero name is {1}, his super power - {0}, his enemy - {2}'.format(super_power, enemy, name))
  • Форматовані літерали (f-рядки): Уведено з Python 3.6. Це рядки, перед якими ставиться префікс f або F. Всередині таких рядків у фігурних дужках {} можна вбудовувати довільні вирази Python – вони обчислюються під час виконання і вставляються в результат як рядок.

print(f'Superhero\'s name is {name}, his super power - {super_power.upper()}, his enemy - {enemy[:2]}.')

Наприклад:

Copy
Edit
name = 'Світ'
year = 2025
f'Привіт, {name}! Зараз {year} рік.'  

Дає рядок "Привіт, Світ! Зараз 2025 рік.". В середині {} можна застосовувати методи, форматні специфікатори, а також оператор = для дебагу (наприклад, f'{x=}' покаже 'x=значення'). F-рядки часто зручніші за % або format() через пряме вбудовування виразів.


📌 Колекції (Collections)


➡️ list (список)

  • Опис: list – змінна (mutable) послідовність довільних об’єктів. Зазвичай використовується для колекцій однорідних або гетерогенних даних.
  • Змінюваність: змінний. Елементи списку можна змінювати, додавати і видаляти без створення нового списку (ідентифікатор списку залишається тим самим при мутації).
  • Стандартні функції:
    • len(lst)
    • type(lst)
    • isinstance(lst, list)
    • sorted(lst) (повертає новий відсортований список)
    • list(iterable) (конвертує інший ітерабельний об’єкт у список).
  • Методи: До list відносяться методи для мутації та обробки:
    • Додавання/вставка: lst.append(x), lst.extend(iterable), lst.insert(index, x).
    • Видалення: lst.remove(x) (видаляє перше входження), lst.pop([index]) (видаляє та повертає елемент; за замовчуванням останній), lst.clear() (видаляє всі елементи).
    • Сортування/реверс: lst.sort(key=..., reverse=False) (сортує на місці), lst.reverse() (реверсує порядок на місці).
    • Копіювання: lst.copy() (поверхнева копія).
    • Суміжні операції: конкатенація (+), множення (*) створюють нові списки; зрізи lst[i:j] дають підсписок.

      Слід пам’ятати, що методи мутації (append, sort тощо) повертають None, а не сам список.

➡️ tuple (кортеж)

  • Опис: tuple – незмінна (immutable) послідовність об’єктів. Часто використовується для структурованих записів (гетерогенних даних) або де потрібно зафіксувати послідовність (напр. ключ у set або dict).
  • Змінюваність: незмінний. Після створення елементи кортежу не можна змінити.
  • Стандартні функції:
    • len(t)
    • type(t)
    • isinstance(t, tuple)
    • sorted(t) (поверне новий список з елементами кортежу, якщо елементи можна порівняти)
    • tuple(iterable) (конвертує в кортеж).
  • Методи: Оскільки кортежі незмінні, вони не мають методів, що мутують. Є базові методи:
    • t.count(x) – кількість входжень x у кортежі.
    • t.index(x) – індекс першого входження x.
    • Інші методи та операції такі ж, як для послідовностей: індексація (t[i]), зрізи, конкатенація та множення створюють нові кортежі.

➡️ set та frozenset (множини)

  • Опис: set – невпорядкований набір унікальних (distinct) хешованих об’єктів. Зазвичай використовується для перевірки належності, усунення дублікатів або математичних операцій над множинами (перетин, об’єднання тощо).
  • Змінюванність: set – змінний, frozenset – незмінний: Вміст звичайного set може змінюватися (методи add(), remove() тощо), тому set не має власного хеша. На відміну від нього, frozenset – незмінний (його можна використовувати як ключ словника чи елемент множини).
  • Стандартні функції:
    • len(s)
    • type(s)
    • isinstance(s, set) (для змінних множин) чи isinstance(s, frozenset) (для незмінних).
    • Перетворювати можна через set(iterable) або frozenset(iterable).
    • sorted(s) поверне відсортований список елементів.
  • Методи (для set):
    • Модифікація: s.add(x) (додати), s.remove(x) (видалити або помилка, якщо немає), s.discard(x) (видалити без помилки), s.pop() (витягнути і повернути довільний елемент), s.clear().
    • Операції з іншими множинами (повертають новий set): s.union(t) або s | t, s.intersection(t) або s & t, s.difference(t) або s - t, s.symmetric_difference(t) або s ^ t.
    • Операції оновлення на місці: s.update(iterables) (додає), s.intersection_update(iterables), s.difference_update(iterables), s.symmetric_difference_update(other).
    • Інші: s.isdisjoint(t), s.issubset(t) (<=), s.issuperset(t) (>=).

      Для frozenset доступні тільки операції, які не змінюють множину (без _update): union, intersection, тощо.

➡️ dict (словник)

  • Опис: dict – відображення (mapping) з ключів у значення. Ключі можуть бути будь-якими хешованими (наприклад, числовими, рядками або frozenset), а значення – довільними об’єктами. Словник зберігає асоціації (ключ: значення) і гарантує впорядкування за вставкою (з Python 3.7).
  • Змінюваність: змінний. У словнику можна додавати, змінювати і видаляти пари ключ–значення без створення нового об’єкта словника.
  • Стандартні функції:
    • len(d)
    • type(d)
    • isinstance(d, dict). Перетворити можна через dict(iterable) або dict(mapping). Наприклад, dict([('a',1),('b',2)]). list(d) повертає список ключів. sorted(d) повертає відсортований список ключів.
  • Методи: Основні методи словника:
    • Отримання/встановлення:
      • d[key] (звернутися за ключем; викликає KeyError, якщо ключу нема, або d.get(key, default) поверне default замість помилки).
      • d[key] = value – додати або оновити значення.
      • del d[key] – видалити пару з ключем (або помилка, якщо ключ не існує).
    • Перегляд ключів і значень:
      • d.keys()
      • d.values()
      • d.items() – повертають «вид» (view) на відповідні колекції (не списки, але їх можна обгорнути в list()).
    • Інші:
      • d.update(other) – оновити словник парами з іншого словника або ітерабельного об’єкта
      • d.pop(key[, default]) – видалити ключ і повернути значення (або default)
      • d.popitem() – видалити і повернути довільну пару (останню за вставкою)
      • d.clear() – очистити словник
      • d.copy() – поверхневий копію.

📌 Приведення типів


Для перетворення між типами Python надає стандартні функції:

  • int(x) – конвертує x у ціле число (якщо можливо). Наприклад, int("123") → 123, int(3.9) → 3.
  • float(x) – конвертує x у число з плаваючою крапкою. Приклад: float("3.14") → 3.14, float(2) → 2.0.
  • str(x) – перетворює об’єкт x на рядок (викликає його метод __str__). Наприклад, str(123) → "123".
  • bool(x) – конвертує x у булеве значення (False для «порожніх» чи нульових даних, інакше True). Наприклад, bool("") → False, bool([1,2]) → True.
  • list(x) – конвертує ітерабельний x в список. Наприклад, list("abc") → ['a','b','c'], list((1,2)) → [1,2]; без аргументів повертає порожній список.
  • tuple(x) – конвертує ітерабельний x в кортеж. Наприклад, tuple("ab") → ('a','b'), tuple([1,2]) → (1,2); без аргументів – пустий кортеж.
  • dict(...) – створює словник. Можна викликати dict() без аргументів (пустий словник), або dict(mapping) з іншим словником, або dict(iterable_of_pairs) – послідовністю з двохелементних ітерабельних (наприклад, dict([('a',1),('b',2)])).
  • set(x) – перетворює x в множину (унікальні елементи з ітерабельного x). Наприклад, set("abracadabra") → {'a','b','r','c','d'}. Без аргументів дає пусту множину set(). Аналогічно, frozenset(x) створює незмінну множину. Кожна з цих функцій намагається інтерпретувати вхідні дані відповідно до нового типу і може викликати помилку (ValueError, TypeError тощо), якщо перетворення неможливе.

➡️ Приведення типів у логічних виразах

(Truthy / Falsy) в Python Логічний вираз — це вираз, який повертає булеве значення: True або False.

if x:
    print("x is True")

У цьому виразі x автоматично перетворюється в булеве значення за певними правилами.

🔹 Загальне правило У логічному контексті (наприклад, if, while, and, or, not) Python виконує неявне приведення типів до bool.

Для цього викликається вбудована функція bool(obj). 🔸 Що вважається False в логічному виразі? Усі ці об’єкти розглядаються як False:

Тип Значення, що вважаються False
NoneType None
bool False
int, float 0, 0.0
str '' (порожній рядок)
list, tuple, set [], (), set()
dict {}
range range(0)
Класи / об'єкти Якщо __bool__() або __len__() повертає 0 або False

🔹 Усе інше вважається True

bool(3.14)        # True
bool("Hello")     # True
bool([0])         # True (непорожній список)
bool(" ")         # True (рядок з пробілом)
bool({'a': 1})    # True (непорожній словник)

🔸 Приклади використання

x = []
if x:
    print("True")
else:
    print("False")  # → False, бо список порожній
x = [0]
if x:
    print("True")  # → True, бо список не порожній
x = ""
print(bool(x))      # False

x = "False"
print(bool(x))      # True (непорожній рядок)

📌 Перевірка типів


для перевірки типу об'єкта можна використати:

type(obj) — вбудована функція для отримання точного типу об'єкта

x = 5
print(type(x))  # <class 'int'>

🔸 Але type() не враховує спадкування. Тобто:

isinstance(obj, Type) — перевірка типу з урахуванням спадкування

x = 5
print(isinstance(x, int))  # ✅ True

class A: pass
class B(A): pass
print(isinstance(B(), A))  # ✅ True

🔹 Можна передати кортеж типів:

print(isinstance("hello", (int, str, float)))  # True

🔸 Найкраща практика — завжди використовуй isinstance() для перевірки типів.

Перевірка через __class__

x = 5
print(x.__class__ is int)  # True

⚠️ Це працює як type(), не враховує спадкування, і зазвичай не рекомендовано.

issubclass(SubType, SuperType) — чи є клас підкласом іншого

class A: pass
class B(A): pass

print(issubclass(B, A))  # True

🧠 Використовується для перевірки ієрархії класів, а не для перевірки об’єктів.


📌 Duck-typing


"If it looks like a duck, swims like a duck, and quacks like a duck, then it probably is a duck." 🦆

Duck typing — це концепція в динамічних мовах програмування (наприклад, Python), де тип об'єкта визначається не його класом чи спадкуванням, а тим, як він поводиться (які методи та атрибути він має).

Суть

  • У Python не важливо якого типу об'єкт ( чи об'єкт є екземпляром певного класу). Тип не перевіряється.
  • Перевіряється функціонал об'єкта (його методи). Якщо вони відповідають певному функціоналу ("може крякати як качка, плавати як качка"), то з ним можна працювати як за "качкою" - з об'єктом певного типу
  • Важливо чи реалізує він потрібні методи або інтерфейс.
  • Це дозволяє писати гнучкий код, який працює з будь-яким об'єктом, якщо той підтримує необхідну поведінку.

📌 Анотації типів (Type Annotations)


Анотації типів допомагають документувати код, покращують читаність і використовуються для статичного аналізу інструментами (наприклад, mypy, Pyright).

Переваги використання анотацій типів

  • можливість запобігання певним помилкам
  • документування коду
  • вдосконалення продуктивності інструментів розробки, лінтерів
  • допомагають побудувати і підтримувати чисту архітектуру додатку

Для анотації типів можна використати:

  • вбудовані прийоми (вказання типу змінної, аргумента функції, типу значення, яке має повертати функція)
  • використання вбудованого модуля typing

Анотації для змінних

age: int = 30
name: str = "Alice"
scores: list[int] = [90, 85, 100]
options: dict[str, bool] = {"debug": True}

Анотації для функцій

def greet(name: str) -> str:
    return f"Hello, {name}"
  • name: str — тип аргументу

  • -> str — тип повернення

Анотації класів

class User:
    ...

def process(user: User) -> None:
    ...
class Test:
    def __init__(self, x):
        self.x = x

    @classmethod
    def create(cls, x: int) -> 'Test':
        return cls(x)

Використання модуля typing

Основні типи

Тип з модуля typing Призначення Альтернатива вбудована в мову з версії 3.9
Any Будь-який тип -
Union Значення кількох типів : Union[int, str, float] int | str | float
Optional[int] int або None int | None
List[X] Список з елементами типу X list[X]
Dict[K, V] Словник з ключами типу K і значеннями типу V dict[K, V]
Tuple[X, Y] Кортеж з типами X і Y tuple[X, Y]
Callable Функції з певною сигнатурою -
TypeVar Універсальний шаблон типу -
Literal Конкретні значення (наприклад, Literal[0, 1]) -