Skip to content

5. Класи та об’єкти

Клас — це форма, за якою створюються об’єкти. Об’єкт називають екземпляром класу.

  

5.1. Клас «Об’єкт»


Програма (classes_01)


# -*- coding=utf-8 -*-

class Objet:
    """une classe Objet vide"""

# кожна змінна за своєю суттю може мати атрибути
obj1=Objet()
obj1.attr1="un"
obj1.attr2=100
# відображає об’єкт
print "objet1=[{0},{1}]".format(obj1.attr1,obj1.attr2)
# змінює об’єкт
obj1.attr2+=100
# виводить об’єкт
print "objet1=[{0},{1}]".format(obj1.attr1,obj1.attr2)
# присвоює посилання на об’єкт1 об’єкту2
obj2=obj1
# змінює об’єкт2
obj2.attr2=0
# відображає обидва об’єкти
print "objet1=[{0},{1}]".format(obj1.attr1,obj1.attr2)
print "objet2=[{0},{1}]".format(obj2.attr1,obj2.attr2)

Примітки:

  • рядок 4: інша форма коментаря. Цей коментар, що починається з трьох символів «, може займати кілька рядків;
  • рядки 3–4: порожній об’єктний клас;
  • рядок 7: створення екземпляра класу Objet;
  • рядок 17: копіювання посилань. Змінні obj1 та obj2 — це два покажчики (посилання) на один і той самий об’єкт.

Результати

1
2
3
4
objet1=[un,100]
objet1=[un,200]
objet1=[un,0]
objet2=[un,0]

5.2. Клас «Особа»


Програма (classes_02)


# -*- coding=utf-8 -*-

class Personne:
    # атрибути класу
    # не оголошені — можуть бути створені динамічно

    # метод
    def identite(self):
        # на перший погляд, використовує атрибути, яких не існує
        return "[{0},{1},{2}]".format(self.prenom,self.nom,self.age)

# ---------------------------------- main
# атрибути є публічними і можуть створюватися динамічно
p=Personne()
p.prenom="Paul"
p.nom="Langevin"
p.age=48
# виклик методу
print "personne={0}\n".format(p.identite())

Примітки:

  • рядки 3–10: клас із методом;
  • рядок 8: перший параметр будь-якого методу класу повинен бути об’єктом self, який позначає поточний об’єкт.

Результати

personne=[Paul,Langevin,48]

5.3. Клас Personne з конструктором


Програма (classes_03)


# -*- coding=utf-8 -*-

class Personne:
    
    # конструктор
    def __init__(self,prenom,nom,age):
        self.prenom=prenom;
        self.nom=nom;
        self.age=age;

    # метод
    def identite(self):
        # на перший погляд, використовує атрибути, яких не існує
        return "[{0},{1},{2}]".format(self.prenom,self.nom,self.age)

# ---------------------------------- main
# об'єкт «Особа»
p=Personne("Paul","Langevin",48)
# виклик методу
print "personne={0}\n".format(p.identite())

Примітки:

  • рядок 6: конструктор класу називається __init__. Як і в інших методах, його першим параметром є self;
  • рядок 18: об’єкт Personne створюється за допомогою конструктора класу.

Результати

personne=[Paul,Langevin,48]

5.4. Клас Personne з перевірками правильності в конструкторі


Програма (classes_04)


# -*- coding=utf-8 -*-

import re

# -------------------
# власний клас винятків
class MyError(Exception):
    pass

class Personne:
    
    # конструктор
    def __init__(self,prenom="x",nom="x",age=0):
         # ім'я має бути не порожнім
        match=re.match(r"^\s*(\S+)\s*$",prenom)
        if not match:
            raise MyError("Le prenom ne peut etre vide")
        else:
            self.prenom=match.groups()[0]
        # прізвище не може бути порожнім
        match=re.match(r"^\s*(\S+)\s*$",nom)
        if not match:
            raise MyError("Le nom ne peut etre vide")
        else:
            self.nom=match.groups()[0]
        # вік має бути дійсним
        match=re.match(r"^\s*(\d+)\s*$",str(age))
        if not match:
            raise MyError("l'age doit etre un entier positif")
        else:
            self.age=match.groups()[0]

    def __str__(self):
        return "[{0},{1},{2}]".format(self.prenom,self.nom,self.age)
      
# ---------------------------------- main
# об’єкт «Особа»
try:
    p=Personne("  Paul  ","  Langevin  ",48)
    print "personne={0}".format(p)
except MyError, erreur:
    print erreur
# інший об’єкт «Особа»
try:
    p=Personne("  xx  ","  yy  ","  zz")
    print "personne={0}".format(p)
except MyError, erreur:
    print erreur
# інша особа
try:
    p=Personne()
    print "personne={0}".format(p)
except MyError, erreur:
    print erreur

Примітки:

  • рядки 7–8: клас MyError, похідний від класу Exception. Він не додає жодних нових функцій до останнього. Він існує лише для того, щоб мати власний виняток;
  • рядок 13: конструктор має значення за замовчуванням для своїх параметрів. Таким чином, операція p=Personne() еквівалентна p=Personne("x","x",0);
  • рядки 15–9: аналізується параметр prenom. Він має бути не порожнім. Якщо це не так, генерується виняток MyError із повідомленням про помилку;
  • рядки 21–25: те саме стосується імені;
  • рядки 27–31: перевірка віку;
  • рядки 33–34: функція __str__ замінює метод, який раніше називався identite;
  • рядки 38–42: створення екземпляра особи та відображення її даних;
  • рядок 39: створення екземпляра;
  • рядок 40: виведення. Операція вимагає вивести особу p у вигляді символьного рядка. Інтерпретатор Python автоматично викликає метод p.__str__(), якщо він існує. Цей метод виконує ту саму роль, що й метод toString() у Java або в мовах .NET;
  • рядки 41–42: обробка можливого винятку типу MyError. Потім виводиться повідомлення про помилку, пов’язане з цим винятком;
  • рядки 44–48: те саме для другого об’єкта, створеного з неправильними параметрами;
  • рядки 50–54: те саме для третьої особи, інстанційованої з параметрами за замовчуванням.

Результати

1
2
3
personne=[Paul,Langevin,48]
l'age doit etre un entier positif
personne=[x,x,0]

5.5. Додано метод, що виконує роль другого конструктора


Програма (classes_05)


# -*- coding=utf-8 -*-

import re

# -------------------
# власний клас винятків
class MyError(Exception):
    pass

class Personne:
    # атрибути класу
    # не оголошені — можуть створюватися динамічно
    
    # конструктор
    def __init__(self,prenom="x",nom="x",age=0):
         # ім'я має бути вказано
        match=re.match(r"^\s*(\S+)\s*$",prenom)
        if not match:
            raise MyError("Le prenom ne peut etre vide")
        else:
            self.prenom=match.groups()[0]
        # прізвище не може бути порожнім
        match=re.match(r"^\s*(\S+)\s*$",nom)
        if not match:
            raise MyError("Le nom ne peut etre vide")
        else:
            self.nom=match.groups()[0]
            # вік має бути дійсним
        match=re.match(r"^\s*(\d+)\s*$",str(age))
        if not match:
            raise MyError("l'age doit etre un entier positif")
        else:
            self.age=match.groups()[0]

    def initWithPersonne(self,p):
        # ініціалізує поточний об’єкт як особу p
        self.__init__(p.prenom,p.nom,p.age)

    def __str__(self):
        return "[{0},{1},{2}]".format(self.prenom,self.nom,self.age)
      
# ---------------------------------- main
# об'єкт «Особа»
try:
    p0=Personne("  Paul  ","  Langevin  ",48)
    print "personne={0}".format(p0)
except MyError, erreur:
    print erreur
# інший об’єкт «Особа»
try:
    p1=Personne("  xx  ","  yy  ","  zz")
    print "personne={0}".format(p1)
except MyError, erreur:
    print erreur
# ще одна особа
p2=Personne()
try:
    p2.initWithPersonne(p0)
    print "personne={0}".format(p2)
except MyError, erreur:
    print erreur

Примітки:

  • відмінність від попереднього скрипта полягає в рядках 35–37. Було додано метод initWithPersonne. Він викликає конструктор __init__. На відміну від типізованих мов, тут немає можливості мати методи з однаковою назвою, що розрізняються за типом параметрів або результатом. Отже, неможливо мати кілька конструкторів, які б створювали об’єкт на основі різних параметрів, у даному випадку об’єкт типу Personne.

Результати

1
2
3
personne=[Paul,Langevin,48]
l'age doit etre un entier positif
personne=[Paul,Langevin,48]

5.6. Список об’єктів Personne


Програма (classes_06)


# -*- coding=utf-8 -*-

class Personne:
    ...

# ---------------------------------- main
# створення списку об’єктів «особа»
groupe=[Personne("Paul","Langevin",48), Personne("Sylvie","Lefur",70)]
# ідентифікаційні дані цих осіб
for i in range(len(groupe)):
  print "groupe[{0}]={1}".format(i,groupe[i])

Примітки:

  • рядки 3–5: клас Personne, що вже описано

Результати

groupe[0]=[Paul,Langevin,48]
groupe[1]=[Sylvie,Lefur,70]

5.7. Створення класу, похідного від класу «Особа»


Програма (classes_07)


# -*- coding=utf-8 -*-

import re

class Personne:
    ...

class Enseignant(Personne):
    def __init__(self,prenom="x",nom="x",age=0,discipline="x"):
        Personne.__init__(self,prenom,nom,age)
        self.discipline=discipline

    def __str__(self):
        return "[{0},{1},{2},{3}]".format(self.prenom,self.nom,self.age,self.discipline)
  

# ---------------------------------- головне
# створення списку об’єктів «Особа» та похідних
groupe=[Enseignant("Paul","Langevin",48,"anglais"), Personne("Sylvie","Lefur",70)]
# ідентифікаційні дані цих осіб
for i in range(len(groupe)):
  print "groupe[{0}]={1}".format(i,groupe[i])

Примітки:

  • рядки 5–6: клас Personne, який вже визначено;
  • рядок 8: оголошує клас Enseignant як похідний від класу «Personne»;
  • рядок 10: конструктор похідного класу Enseignant повинен викликати конструктор батьківського класу Personne;
  • рядки 21–22: для відображення groupe[i] інтерпретатор використовує метод groupe[i].__str__(). Використаний метод __str__() належить до фактичного класу «група[i]», як показано в наведених нижче результатах.

Результати

groupe[0]=[Paul,Langevin,48,anglais]
groupe[1]=[Sylvie,Lefur,70]

5.8. Створення другого класу, похідного від класу «Особа»


Програма (classes_08)


# -*- coding=utf-8 -*-

import re

class Personne:
    ...

class Enseignant(Personne):
    ...
  
class Etudiant(Personne):
    def __init__(self,prenom="x",nom="x",age=0,formation="x"):
        Personne.__init__(self,prenom,nom,age)
        self.formation=formation

    def __str__(self):
        return "[{0},{1},{2},{3}]".format(self.prenom,self.nom,self.age,self.formation)

# ---------------------------------- головна
# створення списку об’єктів «Особа» та похідних
groupe=[Enseignant("Paul","Langevin",48,"anglais"), Personne("Sylvie","Lefur",70), Etudiant("Steve","Boer",22,"iup2 qualite")]
# ідентифікація цих осіб
for i in range(len(groupe)):
  print "groupe[{0}]={1}".format(i,groupe[i])

Примітки:

  • цей скрипт аналогічний попередньому.

Результати

groupe[0]=[Paul,Langevin,48,anglais]
groupe[1]=[Sylvie,Lefur,70]
groupe[2]=[Steve,Boer,22,iup2 qualite]