Классы в python
Содержание:
- Наследование
- Базовые методы перегрузки
- Метод конструктора
- Наследование классов
- Как оценить производительность модели
- Квадратичный Дискриминантный Анализ (QDA)
- проект
- LDA для более чем одного предсказателя
- Built-In Class Attributes
- Creating Classes
- Библиотека math
- Рекомендации по ФП на языке Python
- Строки
- Операции со строками
- Методы работы сос строками
- Accessing Attributes
- post-init parameters
- Готовимся к моделированию
- Создание класса в Python
Наследование
Наследование — это способ создания нового класса на основе старого. Новый класс является производным классом (дочерним). Существующий класс является базовым классом (родительским).
Пример 3: Использование наследования в Python
# родительский класс class Bird: def __init__(self): print("Bird is ready") def whoisThis(self): print("Bird") def swim(self): print("Swim faster") # дочерний класс class Penguin(Bird): def __init__(self): # вызов функции super() super().__init__() print("Penguin is ready") def whoisThis(self): print("Penguin") def run(self): print("Run faster") peggy = Penguin() peggy.whoisThis() peggy.swim() peggy.run()
Результат работы программы:
Bird is ready Penguin is ready Penguin Swim faster Run faster
Сначала мы создали два класса: Bird (родительский класс) и Penguin (дочерний класс). Он наследует функции родительского класса. Это прослеживается в методе swim().
Дочерний класс изменил поведение родительского класса – метод whoisThis(). Также мы расширяем родительский класс, создав новый метод run().
Мы используем функцию super() перед методом __init__(), чтобы извлечь содержимое метода __init__() из родительского класса в дочерний.
Базовые методы перегрузки
В следующей таблице перечислены некоторые общие функции, которые вы можете переопределить в своих собственных классах.
Sr.No. | Метод, описание и пример вызова |
---|---|
1 |
__init__ (self )
Конструктор (с любыми необязательными аргументами) Пример вызова: obj = className (args) |
2 |
__del __ (самостоятельно)
Деструктор, удаляет объект Образец звонка: del obj |
3 |
__repr __ (самостоятельно)
Оцениваемое строковое представление Пример вызова: repr (obj) |
4 |
__str __ (самостоятельно)
Печатное представление строки Пример вызова: str (obj) |
5 |
__cmp__ (self, x)
Сравнение объектов Пример вызова: cmp (obj, x) |
Метод конструктора
Для инициализации данных используется метод конструктора. Он запускается, когдасоздается объект класса. Он также известен, как метод __init__. Это будет первое определение класса:
classShark: def__init__(self): print("This is the constructor method.")
Если в наш пример добавить к классу Shark указанный метод__init__, программа выведет следующее без внесения изменений в экземпляр sammy:
Вывод This is the constructor method. The shark is swimming. The shark is being awesome.
Это связано с тем, что метод конструктора инициализируется автоматически. Вы должны использовать его для любой инициализации в объектах класса.
Создадим метод конструктора, который использует переменную name. Ее мы применим для присвоения имен объектам. Мы передадим name в качестве параметра и зададим self.name, равное name:
shark.py
classShark: def__init__(self, name): self.name = name
Можно изменить строки в функциях, чтобы ссылаться на имена:
shark.py
classShark: def__init__(self, name): self.name = name defswim(self): # Ссылка на имя print(self.name + " is swimming.") defbe_awesome(self): # Ссылка на имя print(self.name + " is being awesome.")
Также мы можем установить имя объекта Shark sammy равным «Sammy», передав его, как параметр класса Shark:
shark.py
classShark: def__init__(self, name): self.name = name defswim(self): print(self.name + " is swimming.") defbe_awesome(self): print(self.name + " is being awesome.") defmain(): # Устанавливаем имя объекта Shark sammy = Shark("Sammy") sammy.swim() sammy.be_awesome() if __name__ == "__main__": main()
Теперь запустим программу:
python shark.py Вывод Sammy is swimming. Sammy is being awesome.
Имя, которое мы передали объекту, выводится. Мы определили метод __init__ с именем параметра (вместе с ключевым словом self) и передали переменную внутри метода.
Метод конструктора инициализируется автоматически, поэтому его не нужно явно вызывать. Достаточно при создании экземпляра класса передать аргументы в круглых скобках, следующих за именем класса.
Если нужно было бы добавить еще один параметр, например возраст, мы могли сделать это, передав его методу __init__:
classShark: def__init__(self, name, age): self.name = name self.age = age
При создании объекта sammy можно передать возраст Сэмми:
sammy = Shark("Sammy", 5)
Чтобы использовать параметр age, также нужно будет создать метод в классе. Методы конструктора позволяют инициализировать определенные атрибуты объекта.
Наследование классов
Вместо того, чтобы начинать с нуля, вы можете создать класс, выведя его из ранее существовавшего класса, перечислив родительский класс в скобках после имени нового класса.
Дочерний класс наследует атрибуты своего родительского класса, и вы можете использовать эти атрибуты, как если бы они были определены в дочернем классе. Дочерний класс также может переопределять элементы данных и методы родительского класса.
Синтаксис
Производные классы объявляются так же, как их родительский класс; однако список базовых классов для наследования дается после имени класса
class SubClassName (ParentClass1): 'Optional class documentation string' class_suite
Пример
#!/usr/bin/python class Parent: # define parent class parentAttr = 100 def __init__(self): print "Calling parent constructor" def parentMethod(self): print 'Calling parent method' def setAttr(self, attr): Parent.parentAttr = attr def getAttr(self): print "Parent attribute :", Parent.parentAttr class Child(Parent): # define child class def __init__(self): print "Calling child constructor" def childMethod(self): print 'Calling child method' c = Child() # instance of child c.childMethod() # child calls its method c.parentMethod() # calls parent's method c.setAttr(200) # again call parent's method c.getAttr() # again call parent's method
Когда приведенный выше код выполняется, он дает следующий результат
Calling child constructor Calling child method Calling parent method Parent attribute : 200
Аналогичным образом вы можете управлять классом из нескольких родительских классов следующим образом:
class A: # define your class A ..... class B: # define your class B ..... class C(A, B): # subclass of A and B .....
Вы можете использовать функции issubclass () или isinstance (), чтобы проверить отношения двух классов и экземпляров.
- Issubclass ( к югу, вир) функция булева возвращает истину , если данный подкласс суб действительно подкласс суперкласса вир .
- Isinstance (объект, класс) Функция булева возвращает истину , если OBJ является экземпляром класса Class или является экземпляром подкласса класса
Как оценить производительность модели
При классификации иногда нет необходимости использовать точность для оценки производительности модели.
Подумайте об анализе сильно несбалансированного набора данных. Например, вы пытаетесь определить, является ли транзакция мошеннической или нет, но только 0,5% вашего набора данных содержит мошенническую транзакцию. Тогда вы можете предсказать, что ни одна из транзакций не будет мошеннической и будет иметь показатель точности 99,5%! Конечно, это очень наивный подход, который не помогает обнаруживать мошеннические транзакции.
Так что мы используем?
Обычно мы используемчувствительностьа такжеспецифичность,
чувствительностьистинный положительный показатель: пропорции фактических положительных значений правильно определены.
специфичностьявляется истинным отрицательным показателем: доля фактических отрицательных значений правильно определена.
Давайте дадим некоторый контекст, чтобы лучше понять. Используя проблему обнаружения мошенничества,чувствительностьдоля мошеннических операций, определенных как мошенническиеспецифичностьэто доля не мошеннических операций, определенных как не мошеннические.
Поэтому в идеальной ситуации нам нужна высокая чувствительность и специфичность, хотя это может измениться в зависимости от контекста. Например, банк может пожелать установить более высокую чувствительность, а не специфичность, чтобы убедиться, что он идентифицирует мошеннические транзакции.
Кривая ROC(рабочая характеристика приемника) подходит для отображения двух типов метрик ошибок, описанных выше. Общая производительность классификатора определяется областью под кривой ROC (ППК). В идеале он должен охватывать верхний левый угол графика и иметь область, близкую к 1.
Пример кривой ROC. Прямая линия является базовой моделью
Квадратичный Дискриминантный Анализ (QDA)
Здесь мы придерживаемся тех же предположений, что и для LDA, но теперь каждое наблюдениеКТИкласс имеет свою собственную ковариационную матрицу
Для QDA дискриминант выражается как:
Дискриминантное уравнение для QDA
Без каких-либо сюрпризов вы заметите, что уравнение теперь квадратичное.
Но почему стоит выбирать QDA вместо LDA?
QDA — лучший вариант для больших наборов данных, так как он имеет тенденцию к меньшему смещению и большей дисперсии.
С другой стороны, LDA больше подходит для небольших наборов данных и имеет более высокое смещение и более низкую дисперсию.
проект
Большой! Теперь, когда мы глубоко понимаем, как работают логистическая регрессия, LDA и QDA, давайте применим каждый алгоритм для решения проблемы классификации.
LDA для более чем одного предсказателя
Расширяя теперь для нескольких предикторов, мы должны предположить, чтоИксвзят измногомерное распределение Гаусса, с классом среднего вектора и общей ковариационной матрицей.
Пример коррелированного и некоррелированного гауссовского распределения показан ниже.
Слева: некоррелированное нормальное распределение. Справа: коррелированное нормальное распределение
Теперь, выражая дискриминантное уравнение с помощью векторной записи, получим:
Дискриминантное уравнение с матричной нотацией
Как видите, уравнение остается прежним. Только на этот раз мы используем векторную нотацию для размещения многих предикторов.
Built-In Class Attributes
Every Python class keeps following built-in attributes and they can be accessed using dot operator like any other attribute −
-
__dict__ − Dictionary containing the class’s namespace.
-
__doc__ − Class documentation string or none, if undefined.
-
__name__ − Class name.
-
__module__ − Module name in which the class is defined. This attribute is «__main__» in interactive mode.
-
__bases__ − A possibly empty tuple containing the base classes, in the order of their occurrence in the base class list.
For the above class let us try to access all these attributes −
#!/usr/bin/python class Employee: 'Common base class for all employees' empCount = 0 def __init__(self, name, salary): self.name = name self.salary = salary Employee.empCount += 1 def displayCount(self): print "Total Employee %d" % Employee.empCount def displayEmployee(self): print "Name : ", self.name, ", Salary: ", self.salary print "Employee.__doc__:", Employee.__doc__ print "Employee.__name__:", Employee.__name__ print "Employee.__module__:", Employee.__module__ print "Employee.__bases__:", Employee.__bases__ print "Employee.__dict__:", Employee.__dict__
When the above code is executed, it produces the following result −
Employee.__doc__: Common base class for all employees Employee.__name__: Employee Employee.__module__: __main__ Employee.__bases__: () Employee.__dict__: {'__module__': '__main__', 'displayCount': <function displayCount at 0xb7c84994>, 'empCount': 2, 'displayEmployee': <function displayEmployee at 0xb7c8441c>, '__doc__': 'Common base class for all employees', '__init__': <function __init__ at 0xb7c846bc>}
Creating Classes
The class statement creates a new class definition. The name of the class immediately follows the keyword class followed by a colon as follows −
class ClassName: 'Optional class documentation string' class_suite
-
The class has a documentation string, which can be accessed via ClassName.__doc__.
-
The class_suite consists of all the component statements defining class members, data attributes and functions.
Example
Following is the example of a simple Python class −
class Employee: 'Common base class for all employees' empCount = 0 def __init__(self, name, salary): self.name = name self.salary = salary Employee.empCount += 1 def displayCount(self): print "Total Employee %d" % Employee.empCount def displayEmployee(self): print "Name : ", self.name, ", Salary: ", self.salary
-
The variable empCount is a class variable whose value is shared among all instances of a this class. This can be accessed as Employee.empCount from inside the class or outside the class.
-
The first method __init__() is a special method, which is called class constructor or initialization method that Python calls when you create a new instance of this class.
-
You declare other class methods like normal functions with the exception that the first argument to each method is self. Python adds the self argument to the list for you; you do not need to include it when you call the methods.
Библиотека math
Для проведения вычислений с действительными числами язык Python содержит много дополнительных функций, собранных в библиотеку, которая называется math. Для использования этих функций в начале программы необходимо подключить библиотеку, что делается командой
import math # подключение модуля библиотеки
После подключения программа получает доступ ко всем функциям, методам и классам, содержащимся в нём. После подключения можно вызвать любую функцию из подключенной библиотеки по следующему правилу: указывается имя модуля и через точку имя функции
имя_модуля.имя_функции
Например, пусть мы хотим вызвать функцию вычисления Синус угла, задаваемого в радианахimport math y = sin(5) # ошибка не подключен модуль mathx = math.sin(5) # записываем имя модуля и через точку имя функции
Можно подключать не весь модуль, а какую-то его часть. Например, программист хочет использовать только одну функцию из математической библиотеки math. Если он подключит всю библиотеку, то будет добавлено более 40 функций, которые будут занимать место. Чтобы добавить в проект какую-то часть, используют ключевое слово from
from <имя подключаемого модуля> import <название функции>
Например.
from math import sin # подключена только одна функция siny = sin(5) # операция выполненаx = cos(5) # ошибка функция cos не подключена
Ниже приведен список основных функций модуля math. Некоторые из перечисленных функций (int, round, abs) являются стандартными и не требуют подключения модуля math для использования.
Рекомендации по ФП на языке Python
Понятие ФП несколько различается по строгости формулировки. Одни понимают применение только функций, немутируемость и наведение мостов с периферией (вводом-выводом). Другие определяют ФП строже и наряду с немутируемостью говорят о применении только чистых функций. Но в любом случае программирование в функциональном стиле не тождественно функциональному программированию. Применение первоклассных функций, лямбд, итераторов, включений, каррирования и сопоставления с шаблонами вовсе не означает немутируемость и чистые функции.
Что делает функции нечистыми?
-
Глобальные мутации, т.е. внесение изменений в глобальное состояние,
-
Недетерминированность функций, т.е. которые для одинаковых входных значений могут возвращать разные результаты, и
-
Операции ввода-вывода.
Пример глобальной мутации:
Пример недетерминированности:
Пример операции ввода-вывода:
Из чистых функций вытекает ссылочная (референциальная) прозрачность. Говорят, что программа или математическое выражение ссылочно прозрачны, если любое подвыражение можно заменить его значением, и это не приведет к изменению значения целого, т. е. скрытые побочные эффекты отсутствуют. Математические рассуждения, преобразования и доказательства корректности могут быть справедливыми только для выражений, обладающих этим свойством. А программы, написанные на обычных императивных языках, не являются ссылочно прозрачными, так как присваивание значений глобальным переменным, в некоторых случаях и локальным, вызывает скрытые побочные эффекты.
Ссылочная прозрачность (1) улучшает тестопригодность программ, т.е. поведение подпрограмм не зависит от контекста, повторный запуск приложения дает одинаковый результаты как следствие отсутствия мутаций, (2) обеспечивается модульность, т.е. поведение функций не зависит от контекста, и чистые функции можно легко составлять в композиции, строя новые формы поведений, (3) упрощает обеспечение конкурентности из-за отсутствия необходимости в синхронизации, т.к. отсутствие совместных мутируемых данных делает синхронизацию ненужной.
Однако, ФП имеет свои недостатки, такие как новизна парадигмы и иногда ухудшение производительности программ. Но в нашем случае главный недостаток состоит в том, что язык Python, как таковой, не является языком функционального программирования. Например, в нем нет библиотеки по работе с неизменяемыми структурами данных и оптимизации стека под хвостовую рекурсию. Однако эффективное функциональное программирование на Python вполне возможно.
В отличие от объектно-ориентированного программирования, которое строит сложные формы поведения с помощью наследования, ФП опирается на композицию функций. Этот принцип перекликается с философией Unix, состоящей из 2 правил:
-
Правило композиции — строить программы так, чтобы иметь возможность легко их соединять с другими программами.
-
Правило модульности — писать простые части, которые можно соединять чистыми интерфейсами.
Указанные выше два простых правила делают ненужными архитектурные шаблоны и принципы ООП, заменяя их функциями! А что, спросите вы, и классы тоже? В Python использование классов не противоречит ФП, если в них отсутствует мутирующие интерфейсы.
Пример класса с мутирующим интерфейсом:
Пример класса без мутирующего интерфейса:
Но лучше использовать замороженные dataclasses и копирование, где необходимо. Иными словами, все классы должны быть замороженными dataclasses.
При всем при этом dataclasses могут быть вполне себе умными!
Также следует использовать сторонние функциональные библиотеки (например, toolz), которые обеспечивают более оптимальную композиционность функций.
Как вариант, использовать декларативные включения в список, включения в словарь и включения в множество в качестве замены функций и , хотя эта рекомендация является факультативной.
И применять архитектурный шаблон «немутируемое ядро — мутируемая оболочка» (aka «функциональное ядро — императивная оболочка»), который позволяет выносить мутацию во вне и производить ее на границах приложения.
Строки
Строка – это последовательность символов. Чаще всего строки – это просто некоторые наборы слов. Слова могут быть как на английском языке, так и почти на любом языке мира.
Операции со строками
string извлекает символ в позиции i
string извлекает последний символ
string извлекает символы в диапазоне от i до j
Методы работы сос строками
string.upper() преобразует строку в верхний регистр
String.lower() преобразует в строку в нижний регистр
string.count(x) подсчитывает, сколько раз появляется x
string.find(x) позиция первой строки вхождения x
string.replace(x, y) заменяет x на y
string.strip(x) удаляет как начальные, так и конечные символы x
string.join (List) объединяет список строк
Accessing Attributes
You access the object’s attributes using the dot operator with object. Class variable would be accessed using class name as follows −
emp1.displayEmployee() emp2.displayEmployee() print "Total Employee %d" % Employee.empCount
Now, putting all the concepts together −
#!/usr/bin/python class Employee: 'Common base class for all employees' empCount = 0 def __init__(self, name, salary): self.name = name self.salary = salary Employee.empCount += 1 def displayCount(self): print "Total Employee %d" % Employee.empCount def displayEmployee(self): print "Name : ", self.name, ", Salary: ", self.salary "This would create first object of Employee class" emp1 = Employee("Zara", 2000) "This would create second object of Employee class" emp2 = Employee("Manni", 5000) emp1.displayEmployee() emp2.displayEmployee() print "Total Employee %d" % Employee.empCount
When the above code is executed, it produces the following result −
Name : Zara ,Salary: 2000 Name : Manni ,Salary: 5000 Total Employee 2
You can add, remove, or modify attributes of classes and objects at any time −
emp1.age = 7 # Add an 'age' attribute. emp1.age = 8 # Modify 'age' attribute. del emp1.age # Delete 'age' attribute.
Instead of using the normal statements to access attributes, you can use the following functions −
-
The getattr(obj, name) − to access the attribute of object.
-
The hasattr(obj,name) − to check if an attribute exists or not.
-
The setattr(obj,name,value) − to set an attribute. If attribute does not exist, then it would be created.
-
The delattr(obj, name) − to delete an attribute.
hasattr(emp1, 'age') # Returns true if 'age' attribute exists getattr(emp1, 'age') # Returns value of 'age' attribute setattr(emp1, 'age', 8) # Set attribute 'age' at 8 delattr(empl, 'age') # Delete attribute 'age'
post-init parameters
In an earlier version of this PEP before InitVar was added, the
post-init function __post_init__ never took any parameters.
The normal way of doing parameterized initialization (and not just
with Data Classes) is to provide an alternate classmethod constructor.
For example:
@dataclass class C: x: int @classmethod def from_file(cls, filename): with open(filename) as fl: file_value = int(fl.read()) return C(file_value) c = C.from_file('file.txt')
Because the __post_init__ function is the last thing called in the
generated __init__, having a classmethod constructor (which can
also execute code immediately after constructing the object) is
functionally equivalent to being able to pass parameters to a
__post_init__ function.
With InitVars, __post_init__ functions can now take
parameters. They are passed first to __init__ which passes them
to __post_init__ where user code can use them as needed.
The only real difference between alternate classmethod constructors
and InitVar pseudo-fields is in regards to required non-field
parameters during object creation. With InitVars, using
__init__ and the module-level replace() function InitVars
must always be specified. Consider the case where a context
object is needed to create an instance, but isn’t stored as a field.
With alternate classmethod constructors the context parameter is
always optional, because you could still create the object by going
through __init__ (unless you suppress its creation). Which
approach is more appropriate will be application-specific, but both
approaches are supported.
Готовимся к моделированию
Теперь, когда мы знакомы с данными, пришло время подготовить их к моделированию. Как упоминалось ранее, объекты имеют буквы, представляющие различные возможные значения, но нам нужно превратить их в числа.
Для этого мы будем использоватькодирование этикеткиа такжегорячая кодировка
Давайте сначала используем кодирование метки в целевом столбце. Запустите следующий код:
И вы заметили, что теперь столбец содержит 1 и 0.
Результат метки, кодирующей столбец «класс»
Теперь ядовитый представлен 1, а съедобный — 0. Теперь мы можем думать о нашем классификаторе как «ядовитый или нет». Ядовитый гриб получает 1 (true), а съедобный гриб — 0 (false).
Следовательно,кодирование этикеткипревратит категорический признак в числовой. Однако не рекомендуется использовать кодирование меток, когда существует более двух возможных значений.
Зачем?
Потому что тогда он будет присваивать каждое значение либо 0, 1 или 2 Это проблема, потому что «2» можно рассматривать какболее важныйи из этого можно извлечь ложные корреляции.
Чтобы избежать этой проблемы, мы используемгорячее кодированиена других особенностях. Чтобы понять, что он делает, давайте рассмотрим форму крышки первой точки входа. Вы видите, что оно имеет значение «х», которое обозначает выпуклую форму колпачка. Однако в наборе данных записано всего шесть разных форм колпачков. Если мы одноразово закодируем функцию, мы должны получить:
Горячее кодирование функции «шапка-форма»
Как видите, форма шапки теперь является векторной. 1 обозначает фактическое значение формы шапки для записи в наборе данных, а остальное заполнено 0. Опять же, вы можете думать о 1 какправдаи 0 какложный.
Недостаток однократного кодирования состоит в том, что он вводит больше столбцов в набор данных. В случае формы колпачка мы переходим от одного столбца к шести столбцам. Для очень больших наборов данных это может быть проблемой, но в нашем случае дополнительные столбцы должны быть управляемыми.
Давайте продолжим и быстро закодируем остальные функции:
И теперь вы должны увидеть:
Набор горячих закодированных данных
Вы заметили, что мы поднялись с 23 столбцов до 118. Это пятикратное увеличение, но их недостаточно, чтобы вызвать проблемы с памятью компьютера.
Теперь, когда наш набор данных содержит только числовые данные, мы готовы начать моделирование и делать прогнозы!
Создание класса в Python
Классы в Python могут моделировать практически все что угодно. Создадим простой класс, который будет описывать конкретный автомобиль:
class Car():
«»»Описание автомобиля»»»
def __init__(self, brand, model):
«»»Инициализирует атрибуты brand и model»»»
self.brand = brand
self.model = model
def sold(self):
«»»Автомобиль продан»»»
(«Автомобиль {self.brand} {self.model} продан «)
def discount(self):
«»»Скидка на автомобиль»»»
(«На автомобиль {self.brand} {self.model} скидка 5%»)
Разберем код по порядку. В начале определяется класс с именем Car (class Car). По общепринятым соглашение название класса начинается с символа верхнего регистра. Круглые скобки в определение класса пусты, так как класс создается с нуля. Далее идет строка документации с кратким описанием. («»»Описание автомобиля»»»).
1.1. Метод __init__()
Функция, являющаяся частью класса, называется методом. Все свойства функций так же относятся и к методам, единственное отличие это способ вызова метода. Метод __init__() — специальный метод, который автоматически выполняется при создание нового экземпляра. Имя метода начинается и заканчивается двумя символами подчеркивания. Метод __init__() определяется с тремя параметрами: self, brand, model. Параметр self обязателен в определение метода и должен стоять перед всеми остальными параметрами. При создании экземпляра на основе класса Car, необходимо передать только два последних аргумента brand и model.
Каждая из двух переменных self.brand = brand и self.model = model снабжена префиксом self и к ним можно обращаться вызовом self.brand и self.model. Значения берутся из параметров brand и model. Переменные, к которым вы обращаетесь через экземпляры, также называются атрибутами.
В классе Car также есть два метода: sold() и discount(). Этим методам не нужна дополнительная информация и они определяются с единственным параметром self. Экземпляры, которые будут созданы на базе этого класса смогут вызывать данные методы, которые просто выводят информацию.
1.2. Создание экземпляра класса
С помощью класса Car мы можем создавать экземпляры для конкретного автомобиля. Каждый экземпляр описывает конкретный автомобиль и его параметры.
car_1 = Car(‘Bmw’, ‘X5’)
Создадим переменную car_1 и присвоим ей класс с параметрами автомобиля которые нужно обязательно передать (brand, model). При выполнение данного кода Python вызывает метод __init__ , создавая экземпляр, описывающий конкретный автомобиль и присваивает атрибутам brand и model переданные значения. Этот экземпляр сохраняется в переменной car_1.
1.3. Обращение к атрибутам класса
К атрибутам экземпляра класса мы можем обращаться через запись:
print(f»{car_1.brand}»)
print(f»{car_1.model}»)
В записи используется имя экземпляра класса и после точки имя атрибута (car_1.brand) или (car_1.model). В итоге на экран выведется следующая информация:
Bmw
X5
1.4. Вызов методов класса
После создания экземпляра на основе класса Car можете вызывать любые методы, написанные в классе. Чтобы вызвать метод, укажите экземпляр (car_1) и вызываемый метод после точки:
car_1.sold()
car_1.discount()
При вызове данных методов, Python выполнит код, написанный в этом методе.
Автомобиль Bmw X5 продан
На автомобиль Bmw X5 скидка 5%