@@ -170,7 +170,10 @@ d.hi()
170170
171171``` python
172172>> D.mro()
173- [ < class ' __main__.D' > , < class ' __main__.B' > , < class ' __main__.C' > , < class ' __main__.A' > , < class ' object' > ]
173+ [ <
174+
175+
176+ class ' __main__.D' > , < class ' __main__.B' > , < class ' __main__.C' > , < class ' __main__.A' > , < class ' object' > ]
174177```
175178
176179Обратите внимание, в конце всегда будет ` object ` , если вы используете любой Python версии 3.
@@ -179,7 +182,7 @@ d.hi()
179182Если по какой-то причине вас не устраивает существующий порядок, есть возможность вызвать метод ровно из того класса,
180183откуда вам надо, но это считается плохой практикой и лучше так не делать, а полностью поменять структуру.
181184
182- Если вам необходимо использовать метод конкретного родителя, например, ` hi() ` класса С, нужно напрямую вызвать его по
185+ Если вам необходимо использовать метод конкретного родителя, например, ` hi() ` класса С, нужно напрямую вызвать его по
183186имени класса, передав ` self ` в качестве аргумента:
184187
185188``` python
@@ -196,12 +199,12 @@ d.call_hi()
196199
197200## Magic methods (Они же иногда называются dunder-методы)
198201
199- Что такое магические методы? Они всё в объектно-ориентированном Python.
200- Это специальные методы, с помощью которых вы можете добавить в ваши классы «магию».
202+ Что такое магические методы? Они всё в объектно-ориентированном Python.
203+ Это специальные методы, с помощью которых вы можете добавить в ваши классы «магию».
201204Они всегда обрамлены двумя нижними подчеркиваниями, два вначале, два в конце (например, ` __init__ ` или ` __lt__ ` ).
202205
203- Это методы, которые отвечают за любые действия под "капотом". Те, которые выполняются неявно. Допустим,
204- вам нужно сложить два объекта через оператор ` + ` , нам нужен магический метод ` __add__ ` , или мы хотим поменять поведение
206+ Это методы, которые отвечают за любые действия под "капотом". Те, которые выполняются неявно. Допустим,
207+ вам нужно сложить два объекта через оператор ` + ` , нам нужен магический метод ` __add__ ` , или мы хотим поменять поведение
205208при удалении ` __del__ ` , поведение при переборе объекта в цикле ` __iter__ ` или ` __next__ ` и т. д.
206209
207210Почти любое действие, которое вам кажется выполняется само собой, скорее всего описано в magic методе.
@@ -224,45 +227,46 @@ a.some_arg_one
224227a.some_arg_two
225228# 22
226229```
227- Такой способ предпочтительнее, чем вначале задавать какое-то бесполезное значение и сразу же его поменять (номер
230+
231+ Такой способ предпочтительнее, чем вначале задавать какое-то бесполезное значение и сразу же его поменять (номер
228232телефона или место на доске из прошлой домашки).
229233
230- Когда я пишу ` x = SomeClass() ` , ` __init__ ` не самое первое, что вызывается. На самом деле, экземпляр объекта создаёт
231- метод ` __new__ ` , а затем аргументы передаются в инициализатор. На другом конце жизненного цикла объекта находится
234+ Когда я пишу ` x = SomeClass() ` , ` __init__ ` не самое первое, что вызывается. На самом деле, экземпляр объекта создаёт
235+ метод ` __new__ ` , а затем аргументы передаются в инициализатор. На другом конце жизненного цикла объекта находится
232236метод ` __del__ ` .
233237
234238Давайте подробнее рассмотрим эти три магических метода:
235239
236240` __new__(cls, [...) `
237241
238242Это первый метод, который будет вызван при инициализации объекта. Он принимает в качестве параметров класс и потом любые
239- другие аргументы, которые будут переданы в ` __init__ ` . Метод ` __new__ ` используется весьма редко, но иногда бывает
240- полезен, в частности, когда класс наследуется от неизменяемого (immutable) типа, такого как кортеж (tuple) или строка.
243+ другие аргументы, которые будут переданы в ` __init__ ` . Метод ` __new__ ` используется весьма редко, но иногда бывает
244+ полезен, в частности, когда класс наследуется от неизменяемого (immutable) типа, такого как кортеж (tuple) или строка.
241245Я не намерен очень детально останавливаться на ` __new__ ` , так как он не очень часто нужен, и этот метод очень хорошо и
242246детально описан в документации.
243247
244248` __init__(self, [...) `
245249
246250Инициализатор класса. Ему передаётся всё, с чем был вызван первоначальный конструктор (так, например, если мы вызываем
247- ` x = SomeClass(10, 'foo') ` , ` __init__ ` получит 10 и 'foo' в качестве аргументов. ` __init__ ` почти повсеместно
251+ ` x = SomeClass(10, 'foo') ` , ` __init__ ` получит 10 и 'foo' в качестве аргументов. ` __init__ ` почти повсеместно
248252используется при определении классов.
249253
250254` __del__(self) `
251255
252- Если ` __new__ ` и ` __init__ ` образуют конструктор объекта, то ` __del__ ` - это его деструктор. Он не определяет поведение
253- для выражения ` del x ` (поэтому этот код не эквивалентен ` x.__del__() ` ). Скорее, он определяет поведение объекта в то
256+ Если ` __new__ ` и ` __init__ ` образуют конструктор объекта, то ` __del__ ` - это его деструктор. Он не определяет поведение
257+ для выражения ` del x ` (поэтому этот код не эквивалентен ` x.__del__() ` ). Скорее, он определяет поведение объекта в то
254258время, когда объект попадает в сборщика мусора. Это может быть довольно удобно для объектов, которые могут требовать
255259дополнительных чисток во время удаления, таких как сокеты или файловые объекты. Однако, нужно быть осторожным, так как
256260нет гарантии, что ` __del__ ` будет вызван, если объект продолжает жить, когда интерпретатор завершает работу.
257261Поэтому ` __del__ ` не может служить заменой для хороших программистских практик (всегда завершать соединение, если
258- закончил с ним работать и тому подобное). Фактически, из-за отсутствия гарантии вызова ` __del__ ` не должен
262+ закончил с ним работать и тому подобное). Фактически, из-за отсутствия гарантии вызова ` __del__ ` не должен
259263использоваться почти никогда; используйте его с осторожностью.
260264
261265#### Магические методы сравнения
262266
263267В Python огромное количество магических методов, созданных для определения интуитивного сравнения между объектами при
264- помощи операторов, а не плохо выглядящих методов (Что лучше? ` a==b ` или ` a.is_equal(b) ` . Кроме того, они предоставляют
265- способ переопределить поведение Python по умолчанию для сравнения объектов (по ссылке). Вот список этих методов и что
268+ помощи операторов, а не плохо выглядящих методов (Что лучше? ` a==b ` или ` a.is_equal(b) ` . Кроме того, они предоставляют
269+ способ переопределить поведение Python по умолчанию для сравнения объектов (по ссылке). Вот список этих методов и что
266270они делают:
267271
268272` __eq__(self, other) `
@@ -442,9 +446,10 @@ class Word(str):
442446
443447` __unicode__(self) `
444448
445- Определяет поведение функции unicode(), вызванной для экземпляра вашего класса. ` unicode() ` похож на ` str() ` , но возвращает
446- строку в Unicode. Будьте осторожны: если клиент вызывает str() на экземпляре вашего класса, а вы определили только
447- ` __unicode__() ` , то это не будет работать. Постарайтесь всегда определять ` __str__() ` для случая, когда кто-то не имеет
449+ Определяет поведение функции unicode(), вызванной для экземпляра вашего класса. ` unicode() ` похож на ` str() ` , но
450+ возвращает
451+ строку в Unicode. Будьте осторожны: если клиент вызывает str() на экземпляре вашего класса, а вы определили только
452+ ` __unicode__() ` , то это не будет работать. Постарайтесь всегда определять ` __str__() ` для случая, когда кто-то не имеет
448453такой роскоши как Unicode.
449454
450455` __format__(self, formatstr) `
@@ -543,7 +548,7 @@ class Word(str):
543548означает то же, что и ` x.__call__() ` . Заметьте, ` __call__() ` принимает произвольное число аргументов; то есть вы можете
544549определить ` __call__() ` так же как любую другую функцию, принимающую столько аргументов, сколько вам нужно.
545550
546- ` __call__() ` , в частности, может быть полезен в классах, чьи экземпляры часто изменяют своё состояние. «Вызвать»
551+ ` __call__() ` , в частности, может быть полезен в классах, чьи экземпляры часто изменяют своё состояние. «Вызвать»
547552экземпляр может быть интуитивно понятным и элегантным способом изменить состояние объекта. Примером может быть класс,
548553представляющий положение некоторого объекта на плоскости:
549554
@@ -564,3 +569,12 @@ class Entity:
564569любое действие можно переопределить при помощи magic методов.
565570
566571[ Хорошая статья по теме] ( https://habr.com/ru/post/186608/ )
572+
573+ Практика:
574+
575+ 1 . Создаем класс студент, задаем ему имя и оценки, через __ init__
576+ 2 . Добавляем метод добавления оценки
577+ 3 . Добавляем метод вычисления среднего балла
578+ 4 . Прописываем меджик метод (или методы) которые позволяют найти студента с наилучшим средним балом из списка
579+ 5 . Создаем класс группы студентов. У группы есть название и список студентов
580+ 6 . Добавляем возможность найти группу в которой учится студент с самым высоким средним баллом
0 commit comments