Skip to content
This repository was archived by the owner on Jul 2, 2024. It is now read-only.

Commit d4c36a8

Browse files
author
Vlad Ponomarov
committed
lecture16 add practice
1 parent a528c76 commit d4c36a8

File tree

1 file changed

+35
-21
lines changed

1 file changed

+35
-21
lines changed

lesson16.md

Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -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
224227
a.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

Comments
 (0)