Ооп python
Содержание:
- Краткое введение в ООП
- Введение в ООП в Python
- What Could Break?
- Инкапсуляция
- Классы
- Удаление атрибутов и объектов
- Creating an Object in Python
- Class Inheritance
- Инкапсуляция в Python
- Variable Annotations
- Логические операторы
- Что такое self?
- Операторы перегрузки
- Наследование
- Inheritance
- Полиморфизм
- Changes to raise
- Скрытие данных
- Дескрипторы
- Список
- Создание класса в Python:
Краткое введение в ООП
Объектно-ориентированное программирование (ООП) – технология разработки сложного программного обеспечения, в которой программа строится в виде совокупности объектов и их взаимосвязей.
Объединение данных и действий, производимых над этими данными, в единое целое, которое называется объектом – является одним из основных принципов ООП.
Основными понятиями являются понятие класса и объекта.
Класс является типом данных, определяемым пользователем и представляет собой структуру в виде данных и методов для работы с данными.
Формально Класс — это шаблон, по которому будет сделан объект.
Объект является экземпляром класса. Объект и экземпляр - это одно и то же.
Вот пример. Форма для изготовления печенья – это класс, а само печенье это объект или экземпляр класса, т.е. это конкретное изделие. Печенье имеет размеры, цвет, состав – это атрибуты класса. Также в классе описываются методы, которые предназначены для чтения или изменения данных объекта.
В Python характеристики объекта, называются атрибутами, а действия, которые мы можем проделывать с объектами, — методами. Методами в Python называют функции, которые определяются внутри класса.
Объект = атрибуты + методы
Введение в ООП в Python
Python — это мультипарадигмальный язык. Это означает, что он поддерживает различные подходы к программированию.
Одной из наиболее популярных парадигм является создание объектов. Она известна как объектно-ориентированное программирование (ООП).
Объект имеет две характеристики:
- атрибуты;
- поведение;
Рассмотрим на примере:
Объект – это попугай:
- имя, возраст, цвет являются атрибутами;
- пение, танцы — это поведение;
Концепция ООП в Python направлена на создание кода для многократного использования. Эта концепция также известна как DRY (Don’t Repeat Yourself).
В Python концепция ООП реализует несколько принципов:
Наследование | Использование элементов из нового класса без изменения существующего класса. |
Инкапсуляция | Скрытие приватных элементов класса от других объектов. |
Полиморфизм | Концепция использования объекта с одинаковым интерфейсом без получения информации о его типе и внутренней структуре. |
What Could Break?
The new design does its very best not to break old code, but there
are some cases where it wasn’t worth compromising the new semantics in
order to avoid breaking code. In other words, some old code may
break. That’s why the -X switch is there; however this shouldn’t be
an excuse for not fixing your code.
There are two kinds of breakage: sometimes, code will print
slightly funny error messages when it catches a class exception but
expects a string exception. And sometimes, but much less often, code
will actually crash or otherwise do the wrong thing in its error
handling.
Non-fatal Breakage
An examples of the first kind of breakage is code that attempts to
print the exception name, e.g.
modulename.classname
Fatal Breakage
More serious is breaking error handling code. This usually happens
because the error handling code expects the exception or the value
associated with the exception to have a particular type (usually
string or tuple). With the new scheme, the type is a class and the
value is a class instance. For example, the following code will
break:
Another example involves code that assumes too much about the type
of the value associated with the exception. For example:
Again, the remedy is to just go ahead and try the tuple unpack, and
if it fails, use the fallback strategy:
Note that the second try-except statement does not specify the
exception to catch — this is because with string exceptions, the
exception raised is «TypeError: unpack non-tuple», while with class
exceptions it is «ValueError: unpack sequence of wrong size». This
is because a string is a sequence; we must assume that error messages
are always more than two characters long!
(An alternative approach would be to use try-except to test for the
presence of the errno attribute; in the future, this would make sense,
but at the present time it would require even more code in order to be
compatible with string exceptions.)
Инкапсуляция
Используя ООП в Python, мы можем ограничить доступ к методам и переменным. Это предотвращает изменение данных вне класса. Такой подход называется инкапсуляцией. В Python мы устанавливаем приватный модификатор доступа, используя в качестве префикса подчеркивание одинарное «_» или двойное «_ _» подчеркивание.
Пример 4: Инкапсуляция данных в Python
class Computer: def __init__(self): self.__maxprice = 900 def sell(self): print("Selling Price: {}".format(self.__maxprice)) def setMaxPrice(self, price): self.__maxprice = price c = Computer() c.sell() # изменяем цену c.__maxprice = 1000 c.sell() # используем функцию сеттера c.setMaxPrice(1000) c.sell()
Когда мы запустим эту программу, результат будет следующим:
Selling Price: 900 Selling Price: 900 Selling Price: 1000
Сначала мы определили класс Computer . Затем использовали метод __init__() для хранения значения максимальной стоимости продажи компьютера.
Мы попытались изменить цену, но не смогли, потому что Python рассматривает __maxprice, как приватные атрибуты. Чтобы изменить значение, мы использовали функцию сеттера. То есть, setMaxPrice(), которая принимает цену в качестве параметра.
Классы
Класс – это прототип объекта.
В коде классы определяются ключевым словом class.
Создайте файл shark.py. Попробуйте определить класс Shark с двумя функциями:
Определяемые в классе функции называются методами.
В данном случае в качестве аргумента используется слово self – оно ссылается на объекты, основанные на этом классе. Для этого параметр self должен всегда быть первым в функции (но не обязательно единственным её параметром).
Новый класс Shark пока что не создал ни одного объекта Shark. То есть, если вы запустите программу shark.py, ничего не произойдёт.
Теперь у вас есть шаблон для создания объектов.
Удаление атрибутов и объектов
Любой атрибут объекта можно удалить в любое время с помощью оператора del. Попробуйте выполнить следующее в оболочке Python, чтобы увидеть результат.
>>> num1 = ComplexNumber(2,3) >>> del num1.imag >>> num1.get_data() Traceback (most recent call last): ... AttributeError: 'ComplexNumber' object has no attribute 'imag' >>> del ComplexNumber.get_data >>> num1.get_data() Traceback (most recent call last): ... AttributeError: 'ComplexNumber' object has no attribute 'get_data'
Мы даже можем удалить сам объект, используя оператор del.
>>> c1 = ComplexNumber(1,3) >>> del c1 >>> c1 Traceback (most recent call last): ... NameError: name 'c1' is not defined
На самом деле все намного сложнее. Когда мы делаем c1 = ComplexNumber (1,3), в памяти создается новый объект-экземпляр, и имя c1 связывается с ним.
В команде del c1 эта привязка удаляется, а имя c1 удаляется из соответствующего пространства имен. Однако объект продолжает существовать в памяти, и если к нему не привязано другое имя, он позже автоматически уничтожается.
Это автоматическое уничтожение объектов, на которые нет ссылок, в Python также называется сборкой мусора.
Было полезно224
Нет28
876-11cookie-checkОбъекты и классы Python
Creating an Object in Python
We saw that the class object could be used to access different attributes.
It can also be used to create new object instances (instantiation) of that class. The procedure to create an object is similar to a function call.
This will create a new object instance named harry. We can access the attributes of objects using the object name prefix.
Attributes may be data or method. Methods of an object are corresponding functions of that class.
This means to say, since is a function object (attribute of class), will be a method object.
Output
<function Person.greet at 0x7fd288e4e160> <bound method Person.greet of <__main__.Person object at 0x7fd288e9fa30>> Hello
You may have noticed the parameter in function definition inside the class but we called the method simply as without any arguments. It still worked.
This is because, whenever an object calls its method, the object itself is passed as the first argument. So, translates into .
In general, calling a method with a list of n arguments is equivalent to calling the corresponding function with an argument list that is created by inserting the method’s object before the first argument.
For these reasons, the first argument of the function in class must be the object itself. This is conventionally called self. It can be named otherwise but we highly recommend to follow the convention.
Now you must be familiar with class object, instance object, function object, method object and their differences.
Class Inheritance
Class inheritance is a fundamental part of object-oriented programming. This allows you to extend your classes by driving properties and methods from parent classes. When one class inherits from another, it automatically has access to all of the attributes and methods of the parent class. You can declare new attributes and methods in the child class, and override attributes and methods of the parent class. To inherit from another class includes the name of the parent class in parentheses when defining the new class. Also, see Composition Over Inheritance.
Instances as attributes
You can store an instance of a class in a different class attribute. This makes it possible for classes to work together to model complex situations.
Инкапсуляция в Python
Это концепция упаковки данных так, что внешний мир имеет доступ только к открытым свойствам. Некоторые свойства могут быть скрыты, чтобы уменьшить уязвимость. Это так называемая реализация сокрытия данных. Например, вы хотите купить брюки с интернет-сайта. Данные, которые вам нужны, это их стоимость и доступность. Количество предметов и их расположение — это информация, которая вас не беспокоит. Следовательно, эта информация скрыта.
В Python это реализуется путем создания private, protected и public переменных и методов экземпляра.
Private свойства имеют двойное подчеркивание (__) в начале, в то время как protected имеют одиночное подчеркивание (_). По умолчанию, все остальные переменные и методы являются public.
Private атрибуты доступны только внутри класса и недоступны для дочернего класса (если он унаследован). Protected доступны внутри класса, но доступны и дочернему классу. Все эти ограничения сняты для public атрибутов.
Следующие фрагменты кода являются примером этой концепции:
Variable Annotations
PEP 526 introduced variable annotations. The style recommendations for them are
similar to those on function annotations described above:
-
Annotations for module level variables, class and instance variables,
and local variables should have a single space after the colon. -
There should be no space before the colon.
-
If an assignment has a right hand side, then the equality sign should have
exactly one space on both sides:# Correct: code: int class Point: coords: Tuple label: str = '<unknown>'
# Wrong: code:int # No space after colon code : int # Space before colon class Test: result: int=0 # No spaces around equality sign
-
Although the PEP 526 is accepted for Python 3.6, the variable annotation
syntax is the preferred syntax for stub files on all versions of Python
(see PEP 484 for details).
Footnotes
Hanging indentation is a type-setting style where all the lines in a paragraph are indented except the first line. In the context of Python, the term is used to describe a style where the opening parenthesis of a parenthesized statement is the last non-whitespace character of the line, with subsequent lines being indented until the closing parenthesis. |
Логические операторы
Логические операторы – одни из самых важных, поскольку позволяют управлять потоком выполнения программы. В Python предусмотрено три оператора этого типа – and, or, not. Их легко запомнить, потому что они идентичны аналогичным словам на английском языке. Соответственно, они обозначают «и», «или», «не» соответственно. Рассмотрим эти операторы подробнее.
И (and). Оператор, выполняющий следующий алгоритм:
- Сравнивает между собой два операнда.
- Если оба выражения являются истинными, возвращается значение True. Если же хотя бы одно из них ложное, то возвращается False.
Приведем пример использования выражения.
>>> a = 7 > 7 and 2 > -1
>>> print(a)
Аналогично примерам, приведенным выше, здесь программа печатает результат выполнения своих операций по предыдущей строчке. Поскольку после обработки обнаружится результат «Ложь», то консоль также выдаст значение False.
Или (or). В этом случае истиной будет считаться тот результат, когда хотя бы одно из условий в операндах является истинным. Если же оба из них ложные, то выдается значение False.
>>> a = 7 > 7 or 2 > -1
>>> print(a)
Не (not). Этот оператор осуществляет инверсию значений. То есть, если на входе находится «Истина», то на выходе будет «Ложь». И наоборот. Так, в примере, который будет чуточку ниже, цифра 0 используется в качестве аргумента функции not. Соответственно, в консоли было выведено обратное значение – True (Ведь 0 – это «ложь» в классификации этого языка).
>>> a = not(0)
>>> print(a)
True
Что такое self?
Классам нужен способ, что ссылаться на самих себя. Это не из разряда нарциссичного отношения со стороны класса. Это способ сообщения между экземплярами. Слово self это способ описания любого объекта, буквально. Давайте взглянем на пример, который мне кажется наиболее полезным, когда я сталкиваюсь с чем-то новым и странным:Добавьте этот код в конец класса, который вы написали ранее и сохраните:
Python
class Vehicle(object):
«»»docstring»»»
def __init__(self, color, doors, tires):
«»»Constructor»»»
self.color = color
self.doors = doors
self.tires = tires
def brake(self):
«»»
Stop the car
«»»
return «Braking»
def drive(self):
«»»
Drive the car
«»»
return «I’m driving!»
if __name__ == «__main__»:
car = Vehicle(«blue», 5, 4)
print(car.color)
truck = Vehicle(«red», 3, 6)
print(truck.color)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
classVehicle(object) «»»docstring»»» def__init__(self,color,doors,tires) «»»Constructor»»» self.color=color self.doors=doors self.tires=tires defbrake(self) «»» Stop the car return»Braking» defdrive(self) «»» Drive the car return»I’m driving!» if__name__==»__main__» car=Vehicle(«blue»,5,4) print(car.color) truck=Vehicle(«red»,3,6) print(truck.color) |
Условия оператора if в данном примере это стандартный способ указать Пайтону на то, что вы хотите запустить код, если он выполняется как автономный файл. Если вы импортировали свой модуль в другой скрипт, то код, расположенный ниже проверки if не заработает. В любом случае, если вы запустите этот код, вы создадите два экземпляра класса автомобиля (Vehicle): класс легкового и класс грузового. Каждый экземпляр будет иметь свои собственные атрибуты и методы. Именно по этому, когда мы выводи цвета каждого экземпляра, они и отличаются друг от друга. Причина в том, что этот класс использует аргумент self, чтобы указать самому себе, что есть что. Давайте немного изменим класс, чтобы сделать методы более уникальными:
Python
class Vehicle(object):
«»»docstring»»»
def __init__(self, color, doors, tires, vtype):
«»»Constructor»»»
self.color = color
self.doors = doors
self.tires = tires
self.vtype = vtype
def brake(self):
«»»
Stop the car
«»»
return «%s braking» % self.vtype
def drive(self):
«»»
Drive the car
«»»
return «I’m driving a %s %s!» % (self.color, self.vtype)
if __name__ == «__main__»:
car = Vehicle(«blue», 5, 4, «car»)
print(car.brake())
print(car.drive())
truck = Vehicle(«red», 3, 6, «truck»)
print(truck.drive())
print(truck.brake())
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
classVehicle(object) «»»docstring»»» def__init__(self,color,doors,tires,vtype) «»»Constructor»»» self.color=color self.doors=doors self.tires=tires self.vtype=vtype defbrake(self) «»» Stop the car return»%s braking»%self.vtype defdrive(self) «»» Drive the car return»I’m driving a %s %s!»%(self.color,self.vtype) if__name__==»__main__» car=Vehicle(«blue»,5,4,»car») print(car.brake()) print(car.drive()) truck=Vehicle(«red»,3,6,»truck») print(truck.drive()) print(truck.brake()) |
В этом примере мы передаем другой параметр, чтобы сообщить классу, какой тип транспортного средства мы создаем. После этого мы вызываем каждый метод для каждого экземпляра. Если вы запустите данный код, вы получите следующий вывод:
Python
car braking
I’m driving a blue car!
I’m driving a red truck!
truck braking
1 2 3 4 |
car braking I’m driving a blue car! I’mdrivingared truck! truck braking |
Это показывает, как экземпляр отслеживает свой аргумент self. Вы также могли заметить, что мы можем переместить переменные атрибутов из метода __init__ в другие методы. Это возможно потому, что все эти атрибуты связанны с аргументом self. Если бы мы этого не сделали, переменные были бы вне области видимости в конце метода __init__ .
Операторы перегрузки
Предположим, что вы создали класс Vector для представления двумерных векторов. Что произойдет, когда вы добавите оператор «плюс»? Скорее всего, Python будет кричать на вас.
Однако вы можете определить метод __add__ в вашем классе для выполнения сложения векторов, и тогда оператор плюс будет вести себя так, как ожидалось:
пример
#!/usr/bin/python class Vector: def __init__(self, a, b): self.a = a self.b = b def __str__(self): return 'Vector (%d, %d)' % (self.a, self.b) def __add__(self,other): return Vector(self.a + other.a, self.b + other.b) v1 = Vector(2,10) v2 = Vector(5,-2) print v1 + v2
Когда приведенный выше код выполняется, он дает следующий результат
Vector(7,8)
Наследование
Наследование — это способ создания нового класса на основе старого. Новый класс является производным классом (дочерним). Существующий класс является базовым классом (родительским).
Пример 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__() из родительского класса в дочерний.
Inheritance
Inheritance is a key concept in object oriented programming. Classes can inherit from other classes. This basically means that you can create a class based on another class.
So we could create a class and base it on the class. We can then add attributes to that only customers will need, such as how much they’ve spent:
# Create the ‘Person’ class
class Person:
def __init__(self, id, firstname, lastname):
self.id = id
self.firstname = firstname
self.lastname = lastname
# Create the ‘Customer’ class (inherited from the ‘Person’ class)
class Customer(Person):
def __init__(self, id, firstname, lastname, totalspend):
Person.__init__(self, id, firstname, lastname)
self.totalspend = totalspend
def getDetails(self):
return «%s %s (customer %i) has spent %s in total.» % (self.firstname, self.lastname, self.id, self.totalspend)
# Instantiate the ‘Customer’ class
customer = Customer(
12,
«Peter»,
«Griffin»,
13000
)
# Print details
print(customer.getDetails())Result
Peter Griffin (customer 12) has spent 13000 in total.
Here we use a (slightly) stripped down version of our class (from the previous example), then we create a class based on it. We know it’s inherited from the class because we’ve put inside the parentheses (like this .
The class has a function called that returns a string of text about how much the customer has spent. This function uses the string formatting tokens and to insert the customer’s details into the right place. The details are provided after the symbol after the end of the string.
Полиморфизм
Полиморфизм — это способность использовать в ООП общий интерфейс для нескольких форм (типов данных).
Предположим, что нужно раскрасить фигуру. Есть несколько вариантов фигуры (прямоугольник, квадрат, круг). Мы могли бы использовать тот же метод, чтобы закрасить любую форму. Эта концепция называется полиморфизмом.
Пример 5: Использование полиморфизма в Python
class Parrot: def fly(self): print("Parrot can fly") def swim(self): print("Parrot can't swim") class Penguin: def fly(self): print("Penguin can't fly") def swim(self): print("Penguin can swim") # общий интерфейс def flying_test(bird): bird.fly() #создаем объекты blu = Parrot() peggy = Penguin() # передаем объекты flying_test(blu) flying_test(peggy)
Результат:
Parrot can fly Penguin can't fly
Мы определили два класса: Parrot и Penguin . У каждого из них есть общий метод fly(), но они разные.
Чтобы реализовать полиморфизм, мы создали общий интерфейс. То есть, функцию flying_test(), которая может принимать любой объект. Затем мы передали объекты blu и peggy в функцию flying_test().
Changes to raise
The statement has been extended to allow raising a class
exception without explicit instantiation. The following forms, called
the «compatibility forms» of the statement, are allowed:
- exception
- exception, argument
- exception, (argument, argument, …)
When exception is a class, these are equivalent to the
following forms:
- exception()
- exception(argument)
- exception(argument, argument, …)
Note that these are all examples of the form
raise instance
which in itself is a shorthand for
raise class, instance
where class is the class to which instance belongs.
In Python 1.4, only the forms
- class, instance and
- instance
were allowed;
in Python 1.5 (starting with 1.5a1) the forms
- class and
- class, argument(s)
were added. The allowable forms for string exceptions are unchanged.
For various reasons, passing None as the second argument to
raise is equivalent to omitting it. In particular, the
statement
raise class, None
is equivalent to
raise class()
and not to
raise class(None)
Likewise, the statement
raise class, value
where
value happens to be a tuple is equivalent to passing the
tuple’s items as individual arguments to the class constructor, rather
than passing value as a single argument (and an empty tuple
calls the constructor without arguments). This makes a difference
because there’s a difference between and
.
These are all compromises — they work well with the kind of
arguments that the standard exceptions typically take (like a simple
string). For clarity in new code, the form
raise class(argument, …)
is recommended (i.e. make an explicit call to the constructor).
How Does This Help?
The motivation for introducing the compatibility forms was to allow
backward compatibility with old code that raised a standard exception.
For example, a __getattr__ hook might invoke the statement
raise AttributeError, attrname
when the desired attribute is not defined.
Using the new class exceptions, the proper exception to raise would
be (attrname); the compatibility
forms ensure that the old code doesn’t break. (In fact, new code that
wants to be compatible with the -X option must use the
compatibility forms, but this is highly discouraged.)
Скрытие данных
Атрибуты объекта могут или не могут быть видны вне определения класса. Вам необходимо присвоить имена атрибутам с двойным префиксом подчеркивания, и тогда эти атрибуты не будут напрямую видны посторонним.
пример
#!/usr/bin/python class JustCounter: __secretCount = 0 def count(self): self.__secretCount += 1 print self.__secretCount counter = JustCounter() counter.count() counter.count() print counter.__secretCount
Когда приведенный выше код выполняется, он дает следующий результат
1 2 Traceback (most recent call last): File "test.py", line 12, in <module> print counter.__secretCount AttributeError: JustCounter instance has no attribute '__secretCount'
Python защищает этих членов, внутренне изменяя имя, чтобы включить имя класса. Вы можете получить доступ к таким атрибутам как object._className__attrName . Если вы заменили свою последнюю строку следующим образом, то она работает для вас
......................... print counter._JustCounter__secretCount
Когда приведенный выше код выполняется, он дает следующий результат
1 2 2
Дескрипторы
Дескрипторы — объекты, которые умеют выполнять произвольный код, когда с ними происходят какие-то действия: доступ, изменение или удаление. Пример:
Дескриптор определяет методы, которые вызываются в момент, когда происходит доступ (или удаление или редактирование) инстанса дескриптора как атрибута другого класса.
Всё это работает благодаря методу : он находит нужный атрибут и проверяет, есть ли у него метод . Если есть — вызывает его, если нет — возвращает сам атрибут.
Именно через механизм дескрипторов осуществляется доступ к атрибутам класса и инстанса. , , и тоже работают благодаря дескрипторам.
Список
Список (list) представляет тип данных, который хранит набор или последовательность элементов. Для создания списка в квадратных скобках через запятую перечисляются все его элементы.
Создание пустого списка
numbers = []
Создание списка чисел:
numbers = # имя списка numbers, он содержит 5 элементов
Создание списка слов:
words = # имя списка words, он содержит 4 элемента
Создание списка из элементов разного типа
listNum = # имя списка listNum, список содержит целые числа и строки
Для управления элементами списки имеют целый ряд методов. Некоторые из них:
append(item): добавляет элемент item в конец списка
insert(index, item): добавляет элемент item в список по индексу index
remove(item): удаляет элемент item. Удаляется только первое вхождение элемента. Если элемент не найден, генерирует исключение ValueError
clear(): удаление всех элементов из списка
index(item): возвращает индекс элемента item. Если элемент не найден, генерирует исключение ValueError
pop(): удаляет и возвращает элемент по индексу index. Если индекс не передан, то просто удаляет последний элемент.
count(item): возвращает количество вхождений элемента item в список
sort(): сортирует элементы. По умолчанию сортирует по возрастанию. Но с помощью параметра key мы можем передать функцию сортировки.
reverse(): расставляет все элементы в списке в обратном порядке
Кроме того, Python предоставляет ряд встроенных функций для работы со списками:
len(list): возвращает длину списка
sorted(list, ): возвращает отсортированный список
min(list): возвращает наименьший элемент списка
Создание класса в Python:
Определение класса начинается с ключевого слова class, после него следует имя класса и двоеточие.
class имя_класса: # тело класса # объявление конструктора # объявление атрибутов # объявление методов
Основные определения
Метод __init__ или Конструктор
В процессе создания объекта атрибутам класса необходимо задать начальные значения
Это действие называется инициализацией. Для этой цели используется специальный метод __init__(), который называется методом инициализации или конструктором. Метод __init__ запускается при создании экземпляра класса — один раз. Обратите внимание на двойные подчёркивания в начале и в конце имени. Синтаксис метода следующий:
def __init__(self, параметр1, параметр2):self.атрибут1 = параметр1 self.атрибут2 = параметр2
Два символа подчеркивания в начале __init__ и два символа подчеркивания в конце обязательны. Параметров у конструктора параметр1, параметр2 может быть сколько угодно, но первым дожен быть параметр self.