Автор видео - талант, не иначе. Так понятно и наглядно объясняешь. Научиться этому - это одно. Ведь нужно еще сначала разобраться в том, что объяснять. Благодарю за контент и помощь в учебе. Как только одно из твоих видео посмотрел, сразу подписался на канал.
Поставь super().__init__() в класс RunningBird(рекомендуется ставить перед кодом этого инита, чтобы инит спустился в самый низ) т.е. перед self.rn_speed = speed. Получится тоже поведение по mro без привязки конкретного имени класса. Спасибо за видео)
Спасибо за видео. Возможно ошибаюсь, но вроде миксины это не классы, поведение которых состоит из нескольких родительских, а родительские классы добавляющие функционал для дочерних. При этом описать поведение Duck при множественном наследовании, можно добавлением метода super в init класса RunningBird с передачей соответствующих параметров.
дыа, я склонен согласиться с такой формулировкой, тут идея в том, что сам процесс множественного наследования трудно было бы подогнать под этот принцип, иначе пришлось бы тупо все возмодные переходы от дочерних к родительским объектам задавать руками, понятнное дело никто бы так делать не хотел, поэтому имеем упрощение, но неявное
возьму на себя ответственность пояснить) по своей сути это и есть пример работы mro только на линейном случае: пока внутри классов ничего не переопределено они ходят за значением a в самого старшего родителя, после первой "инкрементации" ничего не меняется в этой ситуации кроме самого значения a в классе А, но как только в B происходит "инкрементация", под капотом на самом деле выполняются два действия: 1) В.а + 1 - здесь мы идём опять по mro, находим значение 2 в А, увеличиваем на 1 и получаем 3 2) В.а = 3 - вот здесь мы наконец создаём переменную а в В и тем самым перекрываем ею такую же переменную из А, и теперь по нашему mro при обращении B.a ближайшей переменной а окажется именно это свежесозданное значение из самого В, в А больше за ним ходить не нужно факторы, которые стоит учитывать: - поиск атрибутов ведётся банально по строковому имени, то есть "a" в этом примере - "инкрементации" вида N.a += 1 неявно могутт как найти существующее значение в классе N, и увеличить его, так и не найти значение, обратиться за ним к mro, и потом создать это значение в N - советую вывести в консоль или посмотреть в дебаге параметры __dict__ у каждого класса после всех "инкрементаций", будет чётко видно, что и где зранится почитать могу посоветовать документацию только, в книгах такой глубой теории не встречал, вот есть полный разбор алгоритма mro - www.python.org/download/releases/2.3/mro/ - там стоит версия 2.3, но это актуальный алгоритм, на него есть ссылка из документаций всех версий (если крыша после этой статье не отъедет окончательно - можно идти читать исходники)
24:30 разве? если 2 класса неявно наследуют object, то они не могу быть ромбовидными, ведь object всегда будет последним в иерархии mro, и соответственно поиск будет линейным, а не ромбовидным. Если бы было явное наследование, например, если бы и B() и C() явно были бы унаследованы допустим от А(), то тогда можно было бы говорить о ромбовидности. В Python 3 все классы неявно наследуются от object, но на конкретном тайм-коде не ромбовидная структура. Если было бы так, то не существовало бы не ромбовидных структур
"то они не могу быть ромбовидными, ведь object всегда будет последним в иерархии mro, и соответственно поиск будет линейным, а не ромбовидным" - всё верно, только причина и следствие перепутаны местами, сначала возникает ромбовидное наследование от object, а потом применяется mro как решение этой проблемы, без mro был бы ромб
Спасибо большое! Повторение, мать учения. Так ясно и лаконично!
Обалденный урок, спасибо! Примеры не простейшие, а ровно такие, как надо. Без воды, все четко и по полочкам. Второй раз возвращаюсь сюда
Круто! Понравилось!
Братан, хорош, давай, давай, вперёд! Контент в кайф, можно ещё? Вообще красавчик! Можно вот этого вот почаще? )
спасибо, всё будет)
Долгих лет тебе жизни
Автор видео - талант, не иначе. Так понятно и наглядно объясняешь. Научиться этому - это одно. Ведь нужно еще сначала разобраться в том, что объяснять. Благодарю за контент и помощь в учебе. Как только одно из твоих видео посмотрел, сразу подписался на канал.
спасибо за такую высокую оценку)
Очень важные вопросы освещаются! Спасибо!
Поставь super().__init__() в класс RunningBird(рекомендуется ставить перед кодом этого инита, чтобы инит спустился в самый низ) т.е. перед self.rn_speed = speed. Получится тоже поведение по mro без привязки конкретного имени класса. Спасибо за видео)
Спасибо за видео. Возможно ошибаюсь, но вроде миксины это не классы, поведение которых состоит из нескольких родительских, а родительские классы добавляющие функционал для дочерних. При этом описать поведение Duck при множественном наследовании, можно добавлением метода super в init класса RunningBird с передачей соответствующих параметров.
грань между первым и вторым вариантом очень тонкая на самом деле)
На первый взгляд это очень похоже на нарушение дзен питона - явное лучше чем неявное.
Да, некоторые програмисты предпочитают не работать с множественным наследованием.
дыа, я склонен согласиться с такой формулировкой, тут идея в том, что сам процесс множественного наследования трудно было бы подогнать под этот принцип, иначе пришлось бы тупо все возмодные переходы от дочерних к родительским объектам задавать руками, понятнное дело никто бы так делать не хотел, поэтому имеем упрощение, но неявное
особенно если до этого они не встречались в ним в других языках
C3-линеаризация действительно страшные слова )))
Доброго времени суток!
Где можно почитать теорию, которая поможет объяснить следующий кейс со статической переменной?
class A:
a = 1
class B(A):
pass
class C(A)
pass
print(A.a, B.a, C.a) # 1, 1, 1
A.a += 1
print(A.a, B.a, C.a) # 2, 2, 2
B.a += 1
print(A.a, B.a, C.a) # 2, 3, 2
Заранее спасибо!
возьму на себя ответственность пояснить)
по своей сути это и есть пример работы mro только на линейном случае: пока внутри классов ничего не переопределено они ходят за значением a в самого старшего родителя, после первой "инкрементации" ничего не меняется в этой ситуации кроме самого значения a в классе А, но как только в B происходит "инкрементация", под капотом на самом деле выполняются два действия:
1) В.а + 1 - здесь мы идём опять по mro, находим значение 2 в А, увеличиваем на 1 и получаем 3
2) В.а = 3 - вот здесь мы наконец создаём переменную а в В и тем самым перекрываем ею такую же переменную из А, и теперь по нашему mro при обращении B.a ближайшей переменной а окажется именно это свежесозданное значение из самого В, в А больше за ним ходить не нужно
факторы, которые стоит учитывать:
- поиск атрибутов ведётся банально по строковому имени, то есть "a" в этом примере
- "инкрементации" вида N.a += 1 неявно могутт как найти существующее значение в классе N, и увеличить его, так и не найти значение, обратиться за ним к mro, и потом создать это значение в N
- советую вывести в консоль или посмотреть в дебаге параметры __dict__ у каждого класса после всех "инкрементаций", будет чётко видно, что и где зранится
почитать могу посоветовать документацию только, в книгах такой глубой теории не встречал, вот есть полный разбор алгоритма mro - www.python.org/download/releases/2.3/mro/ - там стоит версия 2.3, но это актуальный алгоритм, на него есть ссылка из документаций всех версий
(если крыша после этой статье не отъедет окончательно - можно идти читать исходники)
@@pythonclinic
Спасибо большое за ответ!
24:30 разве?
если 2 класса неявно наследуют object, то они не могу быть ромбовидными, ведь object всегда будет последним в иерархии mro, и соответственно поиск будет линейным, а не ромбовидным. Если бы было явное наследование, например, если бы и B() и C() явно были бы унаследованы допустим от А(), то тогда можно было бы говорить о ромбовидности. В Python 3 все классы неявно наследуются от object, но на конкретном тайм-коде не ромбовидная структура. Если было бы так, то не существовало бы не ромбовидных структур
"то они не могу быть ромбовидными, ведь object всегда будет последним в иерархии mro, и соответственно поиск будет линейным, а не ромбовидным" - всё верно, только причина и следствие перепутаны местами, сначала возникает ромбовидное наследование от object, а потом применяется mro как решение этой проблемы, без mro был бы ромб
Использование классов примесей, это же тоже получается множественное наследование?
конечно, примеси или миксины это оно и есть