Класи і об'єкти

Python підтримує об'єктно-орієнтовану парадигму програмування, а це значить, що ми можемо визначити компоненти програми у вигляді класів.

Клас є шаблоном або формальним описом об'єкта, а об'єкт являє екземпляр цього класу, його реальне втілення. Можна провести наступну аналогію: у всіх у нас є певне уявлення про людину - наявність двох рук, двох ніг, голови, травної, нервової системи, головного мозку і т.д. Є деякий шаблон - цей шаблон можна назвати класом. Реально ж існуюча людина (фактично екземпляр даного класу) є об'єктом цього класу.

З точки зору коду клас об'єднує набір функцій і змінних, які виконують певне завдання. Функції класу ще називають методами. Вони визначають поведінку класу. А змінні класу називають атрибутами - вони зберігають стан класу

Клас визначається за допомогою ключового слова class:

class назва_класу:
    методи_класу

Для створення об'єкта класу використовується наступний синтаксис:

назва_об'екта = назва_класу([параметри])

Наприклад, визначимо найпростіший клас Person, який буде представляти людину:

class Person:
    name = "Tom"
 
    def display_info (self):
        print("Привіт, мене звуть", self.name)
 
person1 = Person ()
person1.display_info() # Привіт, мене звуть Tom
 
person2 = Person()
person2.name = "Sam"
person2.display_info() # Привіт, мене звуть Sam

Клас Person визначає атрибут name, який зберігає ім'я людини, і метод display_info, за допомогою якого виводиться інформація про людину.

При визначенні методів будь-якого класу слід враховувати, що всі вони повинні брати участь у ролі першого параметра посилання на поточний об'єкт, який згідно умовностей називається self (в ряді мов програмування є свого роду аналог - ключове слово this). Через це посилання всередині класу ми можемо звернутися до методів або атрибутів цього ж класу. Зокрема, через вираження self.name можна отримати ім'я користувача.

Після визначення клас Person створюємо пару його об'єктів - person1 і person2. Використовуючи ім'я об'єкта, ми можемо звернутися до його методів і атрибутів. В даному випадку у кожного з об'єктів викликаємо метод display_info(), який виводить рядок на консоль, і у другого об'єкта також змінюємо атрибут name. При цьому при виклику методу display_info не треба передавати значення для параметра self.

Конструктори

Для створення об'єкта класу використовується конструктор. Так, вище коли ми створювали об'єкти класу Person, ми використовували конструктор за замовчуванням, який неявно мають всі класи:

person1 = Person()
person2 = Person()

Однак ми можемо явно визначити в класах конструктор за допомогою спеціального методу, який називається __init (). Наприклад, змінимо клас Person, додавши в нього конструктор:

class Person:
 
    # конструктор
    def __init __(self, name):
        self.name = name # встановлюємо ім'я
 
    def display_info (self):
        print("Привіт, мене звуть", self.name)
 
 
person1 = Person( "Tom")
person1.display_info() # Привіт, мене звуть Tom
person2 = Person("Sam")
person2.display_info() # Привіт, мене звуть Sam

В якості першого параметра конструктор також приймає посилання на поточний об'єкт - self. Нерідко в конструкторах встановлюються атрибути класу. Так, в даному випадку в якості другого параметра в конструктор передається ім'я користувача, яке встановлюється для атрибута self.name. Причому для атрибута необов'язково визначати в класі змінну name, як це було в попередній версії класу Person. Установка значення self.name = name вже неявно створює атрибут name.

person1 = Person("Tom")
person2 = Person("Sam")

У підсумку ми отримаємо наступний консольний вивід:

Привіт, мене звуть Tom
Привіт, мене звуть Sam

Деструкція

Після закінчення роботи з об'єктом ми можемо використовувати оператор del для видалення його з пам'яті:

person1 = Person("Tom")
del person1 # видалення з пам'яті
# person1.display_info() # Цей метод працювати не буде, так як person1 вже видалений з пам'яті

Варто відзначити, що в принципі це необов'язково робити, так як після закінчення роботи скрипта всі об'єкти автоматично видаляються з пам'яті.

Крім того, ми можемо визначити визначити в класі деструктор, реалізувавши вбудовану функцію __del__, який буде викликатися або в результаті виклику оператора del, або при автоматичному видаленні об'єкта. наприклад:

class Person:
    # конструктор
    def __init __(self, name):
        self.name = name # встановлюємо ім'я
 
    def __del __(self):
        print (self.name, "видалений з пам'яті")
    def display_info (self):
        print("Привіт, мене звуть", self.name) 
 
person1 = Person("Tom")
person1.display_info() # Привіт, мене звуть Tom
del person1 # видалення з пам'яті
person2 = Person("Sam")
person2.display_info() # Привіт, мене звуть Sam

Консольний вивід:

Привіт, мене звуть Tom
Tom видалений з пам'яті
Привіт, мене звуть Sam
Sam видалений з пам'яті

Визначення класів в модулях та підключення

Як правило, класи розміщуються в окремих модулях і потім вже імпортуються в основний скрипт програми. Нехай у нас буде в проекті два файли: файл main.py (основний скрипт програми) і classes.py (скрипт з визначенням класів).

Визначення класів Python в модулях та підключення

У файлі classes.py визначимо два класи:

class Person: 
    # конструктор
    def __init __(self, name):
        self.name = name # встановлюємо ім'я
 
    def display_info(self):
        print("Привіт, мене звуть", self.name)
 
 
class Auto:
    def __init __(self, name):
        self.name = name
 
    def move(self, speed):
        print(self.name, "їде зі швидкістю", speed, "км / год")

На додаток до класу Person тут також визначено клас Auto, який представляє машину і який має метод move і атрибут name. Підключимо ці класи і використовуємо їх в скрипті main.py:

from classes import Person, Auto
 
tom = Person("Tom")
tom.display_info()
 
bmw = Auto("BMW")
bmw.move(65)

Підключення класів відбувається точно також, як і функцій з модуля. Ми можемо підключити весь модуль виразом:

import classes

Або підключити окремі класи, як в прикладі вище.

У підсумку ми отримаємо наступний консольний вивід:

Привіт, мене звуть Tom
BMW їде зі швидкістю 65 км/год