✅Викторина. Что произойдёт после запуска программы ?
Cмотрите в комментарий под постом
Cмотрите в комментарий под постом
Anonymous Quiz
10%
Ошибка при создании из-за 1 элемента
48%
Ошибка при создании из-за 3 элемента
28%
Выполнится в штатном режиме
3%
Длина словаря будет строго меньше 3
10%
Какая еще длина словаря? Иди учи мат. часть.
🤔5
❄️ Всех с первым днём зимы!
Ну или у кого что там за окном😁У нас в городе пока вот так👆
Кажется, что снега в этом году могу вообще не увидеть.
А если и будет, то выпадет так быстро, что просплю единственный снегопад))
Как у вас настроение? Чувствуете уже новогодний вайб?🎄
Успеваете доделать то, что планировали на 2025 год?
И ещё вопрос из любопытства: а откуда вы?
Нас тут три с половиной сотни набралось за полгода — интересно, из каких городов и даже стран люди в этом канале!
Где-то, кажется в курсе ПП, видел интерактивную карту поселений участников, мб тоже такое сделать🙃
Рассказывайте в комментах — и про зиму за окном, и про планы, и про ваш город 😊
Ну или у кого что там за окном😁У нас в городе пока вот так👆
Кажется, что снега в этом году могу вообще не увидеть.
А если и будет, то выпадет так быстро, что просплю единственный снегопад))
Как у вас настроение? Чувствуете уже новогодний вайб?🎄
Успеваете доделать то, что планировали на 2025 год?
И ещё вопрос из любопытства: а откуда вы?
Нас тут три с половиной сотни набралось за полгода — интересно, из каких городов и даже стран люди в этом канале!
Где-то, кажется в курсе ПП, видел интерактивную карту поселений участников, мб тоже такое сделать🙃
Рассказывайте в комментах — и про зиму за окном, и про планы, и про ваш город 😊
❤5
issubclass() 🔍 Наследование от встроенных типов
Продолжаем сложные, но интересные объяснения! 😈
📌 Пользовательский класс по умолчанию наследуется от базового класса object.
Зачем? 🤔 Чтобы обеспечить базовый функционал работы с классами!
💡Например: вот эта "абракадабра" с адресом объекта при выводе - это результат работы методa
Атрибут
Три способа проверки на принадлежность класса/объекта к классу:
🔧 С помощью функции issubclass(дочерний_класс, базовый_класс) можем определять,
является ли один класс подклассом другого (именно класс, а не его объекты).
🔧 А вот isinstance(объект, класс) тоже учитывает наследование! 🎯
Эта функция проверяет, является ли объект экземпляром класса или экземпляром любого из его подклассов!
🔧 Есть еще похожая функция type(объект) - она определяет конкретно какому классу принадлежит
переданный объект, без учета наследования.
Тогда мы можем расширить встроенные типы, например list:
Можно стать немножко Java-истами!😄 Складывать строки и числа.
Исходя из последних постов - вы уже знаете, как это сделать.
❓ Как вам такие возможности наследования??? 👇
🔥 — Огонь, приму на вооружение!
🤔 — Знал, но освежил память.
💬 — Есть вопросы в комментарии!
Продолжаем сложные, но интересные объяснения! 😈
class Geom: # <=> class Geom(object):
pass
📌 Пользовательский класс по умолчанию наследуется от базового класса object.
Зачем? 🤔 Чтобы обеспечить базовый функционал работы с классами!
g = Geom()
print(g) #👇
# <__main__.Geom object at 0x0000020B7CDF3FD0>
💡Например: вот эта "абракадабра" с адресом объекта при выводе - это результат работы методa
__str__ из класса objectclass Line(Geom):
pass
l = Line()
print(l.__class__)
📌 Наследование может быть ступенчатым, как видим из этого примера. Атрибут
__class__ тоже взят из того же класса objectТри способа проверки на принадлежность класса/объекта к классу:
🔧 С помощью функции issubclass(дочерний_класс, базовый_класс) можем определять,
является ли один класс подклассом другого (именно класс, а не его объекты).
🔧 А вот isinstance(объект, класс) тоже учитывает наследование! 🎯
Эта функция проверяет, является ли объект экземпляром класса или экземпляром любого из его подклассов!
🔧 Есть еще похожая функция type(объект) - она определяет конкретно какому классу принадлежит
переданный объект, без учета наследования.
print(issubclass(Line, Geom)) # True ← Line наследуется от Geom
print(isinstance(l, Geom)) # True ← объект l принадлежит Geom или его подклассу
print(type(l) == Geom) # False ← объект l не является непосредственным экземпляром Geom
💥 Интересный факт: Все стандартные/встроенные типы данных являются классами. (int, float, list, dict, tuple, set, и т.д.)
Тогда мы можем расширить встроенные типы, например list:
class Vector(list):
def __str__(self): # self - здесь просто список
return ' '.join(map(str, self))
v = Vector([1,2, 3])
print(v) # 1 2 3 вместо [1, 2, 3]
Можно стать немножко Java-истами!😄 Складывать строки и числа.
Исходя из последних постов - вы уже знаете, как это сделать.
❓ Как вам такие возможности наследования??? 👇
🔥 — Огонь, приму на вооружение!
🤔 — Знал, но освежил память.
💬 — Есть вопросы в комментарии!
🔥4
Наследование. Атрибуты private и protected
Напомню про режимы доступа свойств класса:
• public - публичное свойство: - доступно везде
• protected - (с одним подчеркиванием
• private - (с двумя подчеркиваниями
Пример: сделаем в базовом классе все атрибуты приватными.
Получим вот такой вывод (хммм): создавали один класс, а там почему-то переменные из другого класса:
Мало того, если даже добавим метод для получения этих координат в классе Rect, то всё равно ничего не получится — будет ошибка:
Однако если мы переместим этот метод в БАЗОВЫЙ класс, то всё отработает как хотелось бы.
Такое поведение потому, что privat-атрибуты доступны только внутри того класса, где объявлены. Собственно для этого они и создавались.
А если хотим получать доступ к ним в дочерних классах, то уменьшаем количество подчёркиваний на одну. Всё просто)
Protected-атрибуты фактически не запрещает обращаться вне класса. Это условности, которые напоминает, чтобы не обращались к этому атрибуту в другом месте. Не для тебя его роза цвела.😅
ываыаа
Тоже самое касается и приватных методов:
Их можно использовать только внутри текущего класса. Если попытаетесь в другом месте — ошибка отсутствия метода.
Можно еще попробовать другой вариант обхода - в дочернем классе вызывать через super() метод базового класса:
Но нет.. .Так тоже не получиться схитрить и ловим ошибку: ``AttributeError: 'super' object has no attribute '_Rect__verify_coord'``
💬 Вопрос к вам:
А вам вообще интересно, полезно про это читать? Может я зря стараюсь и напрягаюсь?
Практически не вижу реакций под такими постами 😔😔😔
Дайте знать в комментах — нужен фидбек!
👇 Как вам такой формат?!
🔥 — Полезно, продолжай!
🤔 — Есть вопросы /предложения или темы для следующих постов.
Напомню про режимы доступа свойств класса:
• public - публичное свойство: - доступно везде
• protected - (с одним подчеркиванием
_attr): для обращения внутри класса и во всех его дочерних классах• private - (с двумя подчеркиваниями
__attr): для обращения только внутри классаПример: сделаем в базовом классе все атрибуты приватными.
class Geom:
name = 'Geom'
def __init__(self, x1, y1, x2, y2):
print(f"инициализатор Geom для {self.__class__}")
self.__x1 = x1
self.__y1 = y1
self.__x2 = x2
self.__y2 = y2
class Rect(Geom):
def __init__(self, x1, y1, x2, y2, fill='red'):
super().__init__(x1, y1, x2, y2)
self.__fill = fill
r = Rect(1, 2, 3 ,4)
print(r.__dict__)
Получим вот такой вывод (хммм): создавали один класс, а там почему-то переменные из другого класса:
{'_Geom__x1': 1, '_Geom__y1': 2, '_Geom__x2': 3, '_Geom__y2': 4, '_Rect__fill': 'red'}Мало того, если даже добавим метод для получения этих координат в классе Rect, то всё равно ничего не получится — будет ошибка:
def get_coords(self):
return (self.__x1, self.__y1)
print(r.get_coords()) # # AttributeError: 'Rect' object has no attribute '_Rect__x1'
Однако если мы переместим этот метод в БАЗОВЫЙ класс, то всё отработает как хотелось бы.
Такое поведение потому, что privat-атрибуты доступны только внутри того класса, где объявлены. Собственно для этого они и создавались.
А если хотим получать доступ к ним в дочерних классах, то уменьшаем количество подчёркиваний на одну. Всё просто)
Protected-атрибуты фактически не запрещает обращаться вне класса. Это условности, которые напоминает, чтобы не обращались к этому атрибуту в другом месте. Не для тебя его роза цвела.😅
ываыаа
Тоже самое касается и приватных методов:
def __verify_coord(self, coord):
return 0 <= coord <= 100
Их можно использовать только внутри текущего класса. Если попытаетесь в другом месте — ошибка отсутствия метода.
Можно еще попробовать другой вариант обхода - в дочернем классе вызывать через super() метод базового класса:
super().__verify_coord(x1)
Но нет.. .Так тоже не получиться схитрить и ловим ошибку: ``AttributeError: 'super' object has no attribute '_Rect__verify_coord'``
💬 Вопрос к вам:
А вам вообще интересно, полезно про это читать? Может я зря стараюсь и напрягаюсь?
Практически не вижу реакций под такими постами 😔😔😔
Дайте знать в комментах — нужен фидбек!
👇 Как вам такой формат?!
🔥 — Полезно, продолжай!
🤔 — Есть вопросы /предложения или темы для следующих постов.
🔥5
Здесь можно пройти тест на "Какой ты язык программирования". У меня, как видите, совпало) А у вас что вышло?
😈4😁2
Полиморфизм и абстрактные методы
Полиморфизм – это возможность работы с совершенно разными объектами (языка Python) единым образом. (т.е. через единый интерфейс)
Разберемся на примере: пусть есть два класса: для прямоугольников и квадратов:
Получить периметры очевидно можем так:
Но... Если захотим перебрать элементы некого списка объектов [r1, r2, sq1, sq2] и через цикл получить значение периметра, то это будет проблематичнее, ведь у них разные методы для получения данного значения. Можно, конечно, сделать проверку на принадлежность объекта какому-то классу и потом уже вызывать соответствующий метод.
Например так:
А если еще один или несколько классов добавиться, что тогда делать? Добавлять каждый раз ветку и плодить 100500 условий? В данном случае код получается не очень гибким.
Это можно исправить. Вот как раз здесь очень хорошо применим подход, который и называется полиморфизмом. Мы договоримся в каждом классе создавать методы с одинаковыми именами, например - get_pr(). Получается что к разным объектам мы обращаемся через единый интерфейс - это и есть полиморфизм.
Но можно еще немного улучшить эту методику.
Для чего? А в друг мы забудем где-то создать метод для получения периметра. Я, например, могу что-то забыть вполне спокойно😬 Тут есть два пути решения проблемы. Сначала создаем базовый класс а остальным - унаследоваться, затем:
1 способ) В нем прописать метод get_pr().
2 способ) Реализовать через абстрактный метод
• В 1 варианте мы не будем получать ошибок, при вызове - да. Но результат будет не тот, который ожидаем.
• Во 2 варианте будет выдаваться ошибка, которая конкретно указывает что мы забыли переопределить метод в дочернем классе.
Итоговая реализация выглядит вот так:
Подытожим. В языках программирования методы, которые обязательно нужно переопределять в дочерних классах и которые не имеют своей собственной реализации называют абстрактными.
Вы можете заметить, что есть еще абстрактные классы и абстрактные методы. Но об этом в другой раз😏
Комментарии и реакции приветствуются👇
🔥 — Огонь, приму на вооружение!
🤔 — Знал, но освежил память.
💬 — Есть вопросы в комментарии!
Полиморфизм – это возможность работы с совершенно разными объектами (языка Python) единым образом. (т.е. через единый интерфейс)
Разберемся на примере: пусть есть два класса: для прямоугольников и квадратов:
class Rectangle:
def __init__(self, w, h):
self.w = w
self.h = h
def get_rect_pr(self):
return 2 * (self.w + self.h)
class Square:
def __init__(self, a):
self.a = a
def get_sq_pr(self):
return 4 * self.a
r1 = Rectangle(1, 2)
r2 = Rectangle(3, 4)
sq1 = Square(10)
sq2 = Square(20)
Получить периметры очевидно можем так:
print(r1.get_rect_pr(), r2.get_rect_pr())
print(sq1.get_sq_pr(), sq2.get_sq_pr())
Но... Если захотим перебрать элементы некого списка объектов [r1, r2, sq1, sq2] и через цикл получить значение периметра, то это будет проблематичнее, ведь у них разные методы для получения данного значения. Можно, конечно, сделать проверку на принадлежность объекта какому-то классу и потом уже вызывать соответствующий метод.
Например так:
geom = [r1, r2, sq1, sq2]
for g in geom:
if isinstance(g, Rectangle):
print(g.get_rect_pr())
else:
print(g.get_sq_pr())
А если еще один или несколько классов добавиться, что тогда делать? Добавлять каждый раз ветку и плодить 100500 условий? В данном случае код получается не очень гибким.
class Triangle:
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
def get_tr_pr(self):
return self.a + self.b + self.c
Это можно исправить. Вот как раз здесь очень хорошо применим подход, который и называется полиморфизмом. Мы договоримся в каждом классе создавать методы с одинаковыми именами, например - get_pr(). Получается что к разным объектам мы обращаемся через единый интерфейс - это и есть полиморфизм.
Но можно еще немного улучшить эту методику.
Для чего? А в друг мы забудем где-то создать метод для получения периметра. Я, например, могу что-то забыть вполне спокойно😬 Тут есть два пути решения проблемы. Сначала создаем базовый класс а остальным - унаследоваться, затем:
1 способ) В нем прописать метод get_pr().
def get_pr(self):
return -1
2 способ) Реализовать через абстрактный метод
def get_pr(self):
raise NotImplementedError(f"В дочернем классе: {self.__class__.__name__} должен быть переопределен метод get_pr()")
)
• В 1 варианте мы не будем получать ошибок, при вызове - да. Но результат будет не тот, который ожидаем.
• Во 2 варианте будет выдаваться ошибка, которая конкретно указывает что мы забыли переопределить метод в дочернем классе.
Итоговая реализация выглядит вот так:
class Geom:
def get_pr(self):
raise NotImplementedError(f"В дочернем классе: {self.__class__.__name__} должен быть переопределен метод get_pr()")
class Rectangle(Geom):
...
def get_pr(self):
return 2 * (self.w + self.h)
...
class Square(Geom):
...
class Triangle(Geom):
...
Подытожим. В языках программирования методы, которые обязательно нужно переопределять в дочерних классах и которые не имеют своей собственной реализации называют абстрактными.
Вы можете заметить, что есть еще абстрактные классы и абстрактные методы. Но об этом в другой раз😏
Комментарии и реакции приветствуются👇
🔥 — Огонь, приму на вооружение!
🤔 — Знал, но освежил память.
💬 — Есть вопросы в комментарии!
🔥4
🤔 ПРО МОДУЛЬ abc 🤔
В языке Python есть еще один распространенный способ объявления абстрактных методов класса через декоратор abstractmethod модуля abc:
Чтобы корректно работал декоратор abstractmethod сам класс должен наследоваться от базового класса ABC. Например, так:
Мы здесь имеем два абстрактных метода внутри класса Transport, причем, первый метод go() - это обычный метод, а второй abstract_class_method() - это абстрактный метод уровня класса. Обратите внимание на порядок использования декораторов classmethod и abstractmethod. Они должны быть записаны именно в такой последовательности.
Теперь, если объявить какой-либо дочерний класс, например:
То в нем обязательно нужно переопределить абстрактные методы go и abstract_class_method класса Transport. Иначе, объект класса Bus не будет создан (возникнет исключение TypeError).
Также с помощью модуля abc можно определять не только абстрактные методы, но и абстрактные объекты-свойства (property). Делается это следующим образом:
Порядок навешивания декораторов важен! Конечно, вы можете в базовом классе Transport не прописывать "property", и без этого сработает. Но так лучше все-таки делать, чтобы понимать как именно надо реализовывать этот метод в дочернем классе.
Комментарии и реакции приветствуются👇
🔥 — Огонь, приму на вооружение!
🤔 — Знал, но освежил память.
💬 — Есть вопросы в комментарии!
В языке Python есть еще один распространенный способ объявления абстрактных методов класса через декоратор abstractmethod модуля abc:
from abc import ABC, abstractmethod
Чтобы корректно работал декоратор abstractmethod сам класс должен наследоваться от базового класса ABC. Например, так:
class Transport(ABC):
@abstractmethod
def go(self):
"""Метод для перемещения транспортного средства"""
@classmethod
@abstractmethod
def abstract_class_method(cls):
"""Абстрактный метод класса"""
Мы здесь имеем два абстрактных метода внутри класса Transport, причем, первый метод go() - это обычный метод, а второй abstract_class_method() - это абстрактный метод уровня класса. Обратите внимание на порядок использования декораторов classmethod и abstractmethod. Они должны быть записаны именно в такой последовательности.
Теперь, если объявить какой-либо дочерний класс, например:
class Bus(Transport):
def __init__(self, model, speed):
self._model = model
self._speed = speed
def go(self):
print("bus go")
@classmethod
def abstract_class_method(cls):
pass
То в нем обязательно нужно переопределить абстрактные методы go и abstract_class_method класса Transport. Иначе, объект класса Bus не будет создан (возникнет исключение TypeError).
Также с помощью модуля abc можно определять не только абстрактные методы, но и абстрактные объекты-свойства (property). Делается это следующим образом:
from abc import ABC, abstractmethod
class Transport(ABC):
@abstractmethod
def go(self):
"""Метод для перемещения транспортного средства"""
@property
@abstractmethod
def speed(self):
"""Абстрактный объект-свойство getter 'speed' """
@speed.setter
@abstractmethod
def speed(self, value):
"""Абстрактный объект-свойство setter 'speed' """
Порядок навешивания декораторов важен! Конечно, вы можете в базовом классе Transport не прописывать "property", и без этого сработает. Но так лучше все-таки делать, чтобы понимать как именно надо реализовывать этот метод в дочернем классе.
Комментарии и реакции приветствуются👇
🔥 — Огонь, приму на вооружение!
🤔 — Знал, но освежил память.
💬 — Есть вопросы в комментарии!
🔥5
👿Алгоритм Дейкстры или куда пропал мой вчерашний день.👿
Всём доброе утро. Курс по ООП потихоньку подходит к концу. Подошло время очередного испытания - большая задача по темам главы. Как вы возможно догадались, здесь про граф, и к сожалению не про Дракула.
Алгоритм Дейкстры - нахождение кратчайшего пути от вершины до всех остальных вершине в графе, где каждое ребро графа имеет неотрицательную стоимость... .и т.д - загуглите, кому станет интересно.
Собственно сел решать, на 95% всё описал по ТЗ. Казалось бы почти все. Но как же я ошибался😅Это оказалось лишь верхушкой айсберга)
И тут началось самое интересное. Сначала пришлось гуглить и вспоминать как там вообще всё происходит. Последний раз проходил это в универе. Разобраться на примере на бумажке, . Ну вроде бы всё легко и понятно. Осталось дело за малым перенести алгоритм на комп.
Пару подходов с перерывами и я всё ещё практически не сдвинулся с места. Крч, недоделал до конца и забил. Конечно можно было взять готовой алгоритм. Но для чего?) Даже в статейке, где я прочитал про Дейкстру, был пример алгоритма на питоне. Чуть не проспойлерил себе решение. Предлагают импортировать доп. модуль, который предназначен для работы с кучами. После этих слов я перестал читать дальше)) Кажется можно реализовать проще, без всяких этих изыщрений.
А у вас как дела обстоят с графами?)
Всём доброе утро. Курс по ООП потихоньку подходит к концу. Подошло время очередного испытания - большая задача по темам главы. Как вы возможно догадались, здесь про граф, и к сожалению не про Дракула.
Алгоритм Дейкстры - нахождение кратчайшего пути от вершины до всех остальных вершине в графе, где каждое ребро графа имеет неотрицательную стоимость... .и т.д - загуглите, кому станет интересно.
Собственно сел решать, на 95% всё описал по ТЗ. Казалось бы почти все. Но как же я ошибался😅Это оказалось лишь верхушкой айсберга)
И тут началось самое интересное. Сначала пришлось гуглить и вспоминать как там вообще всё происходит. Последний раз проходил это в универе. Разобраться на примере на бумажке, . Ну вроде бы всё легко и понятно. Осталось дело за малым перенести алгоритм на комп.
Пару подходов с перерывами и я всё ещё практически не сдвинулся с места. Крч, недоделал до конца и забил. Конечно можно было взять готовой алгоритм. Но для чего?) Даже в статейке, где я прочитал про Дейкстру, был пример алгоритма на питоне. Чуть не проспойлерил себе решение. Предлагают импортировать доп. модуль, который предназначен для работы с кучами. После этих слов я перестал читать дальше)) Кажется можно реализовать проще, без всяких этих изыщрений.
А у вас как дела обстоят с графами?)
🎃4🔥2
👁Множественное наследование в Python👁
Это когда класс наследуется от нескольких родителей. Не самый частый, но мощный инструмент!
📚 Часть 1: Простой пример
🎯 Главный кейс — миксины (примеси) — классы, которые добавляют одну конкретную фичу другим классам.
👉 Простой пример:
Что происходит?
1. Создаем Notebook → вызывается Goods.init
2 . super().init() в Goods передает управление MixinLog.init
3. Оба инициализатора выполняются
🧠 Как работает super()?
Раньше, уже думаю, ее видели и понимаете что она делает. Я тоже так думал, но оказалось не совсем верно понимал🫣
Оказывается super() возвращает не просто "родительский класс", а следующий класс в MRO (Method Resolution Order) — порядке обхода классов при наследовании.
👉 Цепочка вызовов в данном примере:
1. Notebook() → Goods.init()
2. super().init() в Goods вызывает MixinLog.init()
3. super().init() в MixinLog вызывает object.init()
4. Все инициализаторы выполнены!
🔍 Важно: порядок имеет значение!
Порядок наследования (Goods, MixinLog) определяет MRO (Method Resolution Order):
💎 Правила для миксинов:
1. Делайте их максимально простыми и узкоспециализированными
2. Всегда вызывайте super().init() в init
3. Ставьте миксины после основного класса в наследовании
🎯 Зачем это нужно?
• Переиспользование кода без дублирования
• Гибкое расширение функциональности
• Чистая архитектура (разделение ответственности)
📌 Итог:
Миксины — это как LEGO для классов. Добавляйте готовые блоки функциональности, не ломая основную логику!
А вы использовали множественное наследование или миксины на практике? 👇
Это когда класс наследуется от нескольких родителей. Не самый частый, но мощный инструмент!
📚 Часть 1: Простой пример
🎯 Главный кейс — миксины (примеси) — классы, которые добавляют одну конкретную фичу другим классам.
👉 Простой пример:
class Goods: # Товары
def __init__(self, name, weight, price):
super().__init__() # 🔑 ключевой момент!
self.name = name
self.weight = weight
self.price = price
def print_info(self):
print(f"{self.name}, {self.weight}, {self.price}")
class MixinLog:
ID = 0
def __init__(self):
super().__init__() # здесь для примера
MixinLog.ID += 1
self.id = MixinLog.ID
def save_sell_log(self):
print(f"Товар с id={self.id} был продан в {datetime.now()}")
# Множественное наследование
class Notebook(Goods, MixinLog):
pass
n = Notebook('Acer', 1.5, 30000)
n.print_info() # Acer, 1.5, 30000
n.save_sell_log() # ✅ работает!
Что происходит?
1. Создаем Notebook → вызывается Goods.init
2 . super().init() в Goods передает управление MixinLog.init
3. Оба инициализатора выполняются
🧠 Как работает super()?
Раньше, уже думаю, ее видели и понимаете что она делает. Я тоже так думал, но оказалось не совсем верно понимал🫣
Оказывается super() возвращает не просто "родительский класс", а следующий класс в MRO (Method Resolution Order) — порядке обхода классов при наследовании.
👉 Цепочка вызовов в данном примере:
1. Notebook() → Goods.init()
2. super().init() в Goods вызывает MixinLog.init()
3. super().init() в MixinLog вызывает object.init()
4. Все инициализаторы выполнены!
🔍 Важно: порядок имеет значение!
Порядок наследования (Goods, MixinLog) определяет MRO (Method Resolution Order):
print(Notebook.__mro__)
# (<class '__main__.Notebook'>,
# <class '__main__.Goods'>,
# <class '__main__.MixinLog'>,
# <class 'object'>)
💎 Правила для миксинов:
1. Делайте их максимально простыми и узкоспециализированными
2. Всегда вызывайте super().init() в init
3. Ставьте миксины после основного класса в наследовании
🎯 Зачем это нужно?
• Переиспользование кода без дублирования
• Гибкое расширение функциональности
• Чистая архитектура (разделение ответственности)
📌 Итог:
Миксины — это как LEGO для классов. Добавляйте готовые блоки функциональности, не ломая основную логику!
А вы использовали множественное наследование или миксины на практике? 👇
👍4
📚 Часть 2: MRO и конфликты методов в Python
🔍 Что такое MRO на самом деле?
MRO (Method Resolution Order) — это алгоритм, который определяет порядок поиска методов и атрибутов при множественном наследовании.
🎯 Как Python вычисляет MRO?
Используется алгоритм C3 Linearization. Главные правила:
• Дочерний класс всегда перед родительским
• Порядок наследования сохраняется
• Более левые классы в наследовании имеют приоритет
⚔️ Разрешение конфликтов методов
Рассмотрим ситуацию, когда несколько родительских классов имеют методы с одинаковыми именами, и как можно управлять их вызовом:
🔍 1-й вариант: Оставить как есть (используется первый по MRO)
Почему? MRO для класса MFP: MFP → Printer → Scanner → Copywriter → object. Python находит метод action() в классе Printer первым и останавливается.
🎯 2-й вариант: явный вызов метода из конкретного класса
Важно: При таком вызове нужно явно передавать объект (mfp) первым аргументом, так как мы вызываем метод класса, а не объекта.
🔧 3-й вариант: Переопределить метод в дочернем классе
📊 Когда что использовать:
1-й способ — когда порядок MRO вас устраивает и конфликтов нет
2-й способ — для разового вызова метода из конкретного родителя
3-й способ — для постоянного изменения поведения или комбинирования логики
⚠️ Замечание:
Хотя явный вызов методов через Класс.метод(объект) работает, это жёсткая привязка к конкретному классу. Если изменится иерархия наследования, такой код может сломаться. Переопределение метода в дочернем классе — более гибкий и поддерживаемый подход.
💡Напоминаю - проверить MRO можно всегда:
Вывод: В Python есть гибкие механизмы для работы с наследованием. Выбирайте подход в зависимости от задачи — от простого использования MRO до полного контроля через переопределение методов.
🔍 Что такое MRO на самом деле?
MRO (Method Resolution Order) — это алгоритм, который определяет порядок поиска методов и атрибутов при множественном наследовании.
class A:
def method(self):
print("A")
class B(A):
def method(self):
print("B")
class C(A):
def method(self):
print("C")
class D(B, C):
pass
print(D.__mro__)
# (<class '__main__.D'>, <class '__main__.B'>,
# <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
d = D()
d.method() # Вывод: "B" (первый в MRO)
🎯 Как Python вычисляет MRO?
Используется алгоритм C3 Linearization. Главные правила:
• Дочерний класс всегда перед родительским
• Порядок наследования сохраняется
• Более левые классы в наследовании имеют приоритет
⚔️ Разрешение конфликтов методов
Рассмотрим ситуацию, когда несколько родительских классов имеют методы с одинаковыми именами, и как можно управлять их вызовом:
class Printer:
def action(self):
return "Печатаю"
class Scanner:
def action(self):
return "Сканирую"
class Copywriter:
def action(self):
return "Копирую"
class MFP(Printer, Scanner, Copywriter):
pass
🔍 1-й вариант: Оставить как есть (используется первый по MRO)
mfp = MFP()
print(mfp.action()) # 👉 "Печатаю"
Почему? MRO для класса MFP: MFP → Printer → Scanner → Copywriter → object. Python находит метод action() в классе Printer первым и останавливается.
🎯 2-й вариант: явный вызов метода из конкретного класса
print(Scanner.action(mfp)) # 👉 "Сканирую"
Важно: При таком вызове нужно явно передавать объект (mfp) первым аргументом, так как мы вызываем метод класса, а не объекта.
🔧 3-й вариант: Переопределить метод в дочернем классе
class MFP(Printer, Scanner, Copywriter):
def action(self):
return Scanner.action(self)
# Своя уникальная логика
# return "Я МФУ, делаю всё!"
mfp2 = MFP()
print(mfp2.action()) # "Копирую"
📊 Когда что использовать:
1-й способ — когда порядок MRO вас устраивает и конфликтов нет
2-й способ — для разового вызова метода из конкретного родителя
3-й способ — для постоянного изменения поведения или комбинирования логики
⚠️ Замечание:
Хотя явный вызов методов через Класс.метод(объект) работает, это жёсткая привязка к конкретному классу. Если изменится иерархия наследования, такой код может сломаться. Переопределение метода в дочернем классе — более гибкий и поддерживаемый подход.
💡Напоминаю - проверить MRO можно всегда:
print(MFP.__mro__)
# (<class '__main__.MFP'>, <class '__main__.Printer'>,
# <class '__main__.Scanner'>, <class '__main__.Copywriter'>, <class 'object'>)
Вывод: В Python есть гибкие механизмы для работы с наследованием. Выбирайте подход в зависимости от задачи — от простого использования MRO до полного контроля через переопределение методов.
🔥3
🎯 Коллекция __slots__ в Python. Что это?
🔧 Пример использования:
⚠️ Важный момент:
# При slots у объектов нет dict
💪 3 главных преимущества:
1️⃣ 🔒 Ограничение свойств
• Можно создавать ТОЛЬКО атрибуты из slots
• Защита от опечаток и случайных атрибутов
2️⃣ 💾 Экономия памяти
• У объектов не создается `__dict__` (обычный словарь атрибутов)
• Атрибуты хранятся более эффективно
• Экономия 20-50% памяти на каждый объект
3️⃣ ⚡️ Ускорение работы
• Быстрее читать/писать разрешённые атрибуты
• Прямой доступ вместо поиска в словаре
🎯 Идеально для:
• Фиксированных структур данных
• Массового создания объектов
• Оптимизации памяти в сервисах
__slots__ — это специальный атрибут класса, который определяет разрешённые имена локальных свойств экземпляров.🔧 Пример использования:
class Point:
__slots__ = ('x', 'y') # Разрешаем ТОЛЬКО 'x' и 'y'
def __init__(self, x, y):
self.x = x # ✅ Можно
self.y = y # ✅ Можно
p = Point(1, 2)
p.z = 3 # ❌ Ошибка! Только 'x' и 'y'
⚠️ Важный момент:
# При slots у объектов нет dict
print(p.__dict__) # ❌ AttributeError!
💪 3 главных преимущества:
1️⃣ 🔒 Ограничение свойств
• Можно создавать ТОЛЬКО атрибуты из slots
• Защита от опечаток и случайных атрибутов
2️⃣ 💾 Экономия памяти
• У объектов не создается `__dict__` (обычный словарь атрибутов)
• Атрибуты хранятся более эффективно
• Экономия 20-50% памяти на каждый объект
3️⃣ ⚡️ Ускорение работы
• Быстрее читать/писать разрешённые атрибуты
• Прямой доступ вместо поиска в словаре
🎯 Идеально для:
• Фиксированных структур данных
• Массового создания объектов
• Оптимизации памяти в сервисах
🔥4
🎯 __slots__ с property и при наследовании
Рассмотрим два важных аспекта использования
🔧 slots и property
• Возьмём за основу класс Point из прошлого поста.
• Добавим в slots еще одно допустимое свойство - 'length'.
• А что будет, если добавить property с таким же именем 'length'?
✅ Работает отлично! Потому что:
• length в property — это атрибут класса, а не локальное свойство экземпляра.
• slots не запрещает работу с такими атрибутами!
🔧 slots и наследование
Базовый класс:
❌ Дочерний класс БЕЗ __slots__:
📌 Важно: если не определить slots в дочернем классе, у объектов появится dict и можно создавать любые атрибуты!
✅ Дочерний класс С __slots__:
🎯 Ключевые моменты:
1)
2) Наследование требует явного указания
3) Слоты объединяются — дочерний класс получает все слоты из цепочки наследования
4) Без
📝 Правило для наследования:
Если базовый класс имеет
Используйте slots осознанно, учитывая эти нюансы! 🚀
Рассмотрим два важных аспекта использования
__slots__ — взаимодействие с декоратором property и особенности наследования.🔧 slots и property
• Возьмём за основу класс Point из прошлого поста.
• Добавим в slots еще одно допустимое свойство - 'length'.
• А что будет, если добавить property с таким же именем 'length'?
class Point2D:
__slots__ = ('x', 'y', '__length') # Используем защищенный атрибут
def __init__(self, x, y):
self.x = x
self.y = y
self.__length = (x**2 + y**2)**0.5
@property
def length(self):
return self.__length
@length.setter
def length(self, value):
self.__length = value
✅ Работает отлично! Потому что:
• length в property — это атрибут класса, а не локальное свойство экземпляра.
• slots не запрещает работу с такими атрибутами!
🔧 slots и наследование
Базовый класс:
class Point:
__slots__ = ('x', 'y')
def __init__(self, x, y):
self.x = x
self.y = y
❌ Дочерний класс БЕЗ __slots__:
class Point3D(Point):
pass
pt3 = Point3D(10, 20)
pt3.z = 30 # ✅ Работает!
print(pt3.__dict__) # {'z': 30} - x и y не в dict!
📌 Важно: если не определить slots в дочернем классе, у объектов появится dict и можно создавать любые атрибуты!
✅ Дочерний класс С __slots__:
class Point3D(Point):
__slots__ = ('z',) # Добавляем только новые атрибуты
pt3 = Point3D(10, 20)
pt3.z = 30 # ✅ Работает
pt3.w = 40 # ❌ Ошибка! Только x, y, z разрешены
🎯 Ключевые моменты:
1)
__slots__ работает с property — используйте защищенные имена (__length) в слотах2) Наследование требует явного указания
__slots__ в дочерних классах3) Слоты объединяются — дочерний класс получает все слоты из цепочки наследования
4) Без
__slots__ в потомке — объекты получают __dict__ и теряют преимущества оптимизации📝 Правило для наследования:
Если базовый класс имеет
__slots__, определите __slots__ и в дочернем классе, даже если он пустой!class Child(Parent):
__slots__ = () # Пустой кортеж сохраняет оптимизацию
Используйте slots осознанно, учитывая эти нюансы! 🚀
👍3
✅ Завершил курс Балакирева по ООП. ✅ Не прошло и пол года, как говорится))
В наилучшем исходе рассчитывал пройти дней за 20, ожидаемо - 30. А прошло два месяца😅Ну это смотря как считать.🙃 Очевидно что не все 60 дней я усердно занимался. Недели две, а то и три, можно смело выкинуть на помойку. И уже получается 40 дней. В принципе адекватное время, учитывая что там как раз около 40 тем.
В день я занимался(когда не дурака валял) часов по 4-5+. Некоторые темы легче давались сложнее, некоторые легче. Другие вообще можно было пачкой сделать за один оборот земли своей оси. Но к сожалению у меня так не работает😐. И после одного цельного блока информация уже уходил на отдых. Может решил себя не грузить, чтобы всё усвоилось. А может расслаблялся слишком порой. Или же концепция ООП долго до меня доходит. Чаще получалось так: сначала надо было понять что от меня хотят, подумать как это сделать, и только потом уж писать код.
В общем, курс можно пройти за 30 дней(как и планировал), не особо сильно напрягаясь, но и не халтурить при этом). К сожалению ожидание не всегда совпадает с реальностью.🫠 На днях запишу более подробный отзыв о курсе.
Осталось еще пара-тройка скипнутых задач. На удивление не по связным спискам)) Наверно этим и займусь на ближайших выходных, но это не точно😅 Еще хотелось бы довести до ума сапера, крестики-нолки, ииии морской бой, чтобы это было играбельно всё. Тут уж от настроения зависит... Затем пойду тыкать Django.🫡
А у вас какие планы на выходные?) Все уже ёлку нарядили дома?)
В наилучшем исходе рассчитывал пройти дней за 20, ожидаемо - 30. А прошло два месяца😅Ну это смотря как считать.🙃 Очевидно что не все 60 дней я усердно занимался. Недели две, а то и три, можно смело выкинуть на помойку. И уже получается 40 дней. В принципе адекватное время, учитывая что там как раз около 40 тем.
В день я занимался(когда не дурака валял) часов по 4-5+. Некоторые темы легче давались сложнее, некоторые легче. Другие вообще можно было пачкой сделать за один оборот земли своей оси. Но к сожалению у меня так не работает😐. И после одного цельного блока информация уже уходил на отдых. Может решил себя не грузить, чтобы всё усвоилось. А может расслаблялся слишком порой. Или же концепция ООП долго до меня доходит. Чаще получалось так: сначала надо было понять что от меня хотят, подумать как это сделать, и только потом уж писать код.
В общем, курс можно пройти за 30 дней(как и планировал), не особо сильно напрягаясь, но и не халтурить при этом). К сожалению ожидание не всегда совпадает с реальностью.🫠 На днях запишу более подробный отзыв о курсе.
Осталось еще пара-тройка скипнутых задач. На удивление не по связным спискам)) Наверно этим и займусь на ближайших выходных, но это не точно😅 Еще хотелось бы довести до ума сапера, крестики-нолки, ииии морской бой, чтобы это было играбельно всё. Тут уж от настроения зависит... Затем пойду тыкать Django.🫡
А у вас какие планы на выходные?) Все уже ёлку нарядили дома?)
🔥5🎉3❤1🤝1
В начале нового года на Stepik планируют изменить интерфейс платформы. Пару недель назад висело объявление о прохождении тестирования.
Собственно вот ссылка - макет на figma. Это пока что прототип. Если захотите - посмотрите, потыкайте. Кнопка 'R', возвращает на начальный экран.
На мой взгляд там сильно ничего не поменяли, местами немного не привычно. Однако пару полезных моментов появилось.
P.S. Мне интересно, найдете ли вы быстро кнопку "развернуть"?)
Собственно вот ссылка - макет на figma. Это пока что прототип. Если захотите - посмотрите, потыкайте. Кнопка 'R', возвращает на начальный экран.
На мой взгляд там сильно ничего не поменяли, местами немного не привычно. Однако пару полезных моментов появилось.
P.S. Мне интересно, найдете ли вы быстро кнопку "развернуть"?)
🔥5👏3
И снова здравствуйте!) Немного о наболевшем.
Не знаю как у вас, но заметил за собой момент - если надо идти дальше, изучать что-то новое, то часто всячески этому сопротивляюсь. Придумаю 1000 причин, найду более важные срочные дела, т.е. делается всё что угодно, чтобы не выходить из зоны комфорта. 🙂
Это не есть хорошо. Например, после последнего(надеюсь)) курса по базе питона был вообще отдых в неделю, после ООП - уже тоже дней 5 ничего не делаю толком. А всё потому что надо двигаться дальше. И хочется и не хочется одновременно🙂
Есть конечно еще и другая причина - перенапрягся за последнее время. Бывает даже после хорошего сна не могу и 2 часа просидеть за компом - начинают болеть глаза(в частности почему-то именно один здоровый). И приходится делать огромный перерыв. Или вообще больше не заниматься в этот день, т.к. допустим что-то смотреть/слушать еще могу, а вот читать текст или писать/прогать - нет. Сразу неприятные ощущения и красные глаза😔. Такие дела😒
Но текущих знаний пока маловато для нынешнего рынка труда, поэтому надо как-то двигаться дальше. Теперь в планах Django. Надо вспоминать что это такое вообще). До конца года сделаю проект на нем, а потом буду более подробно разбираться во фреймворке на курсе. Уже потихоньку начал🙃
Не знаю как у вас, но заметил за собой момент - если надо идти дальше, изучать что-то новое, то часто всячески этому сопротивляюсь. Придумаю 1000 причин, найду более важные срочные дела, т.е. делается всё что угодно, чтобы не выходить из зоны комфорта. 🙂
Это не есть хорошо. Например, после последнего(надеюсь)) курса по базе питона был вообще отдых в неделю, после ООП - уже тоже дней 5 ничего не делаю толком. А всё потому что надо двигаться дальше. И хочется и не хочется одновременно🙂
Есть конечно еще и другая причина - перенапрягся за последнее время. Бывает даже после хорошего сна не могу и 2 часа просидеть за компом - начинают болеть глаза(в частности почему-то именно один здоровый). И приходится делать огромный перерыв. Или вообще больше не заниматься в этот день, т.к. допустим что-то смотреть/слушать еще могу, а вот читать текст или писать/прогать - нет. Сразу неприятные ощущения и красные глаза😔. Такие дела😒
Но текущих знаний пока маловато для нынешнего рынка труда, поэтому надо как-то двигаться дальше. Теперь в планах Django. Надо вспоминать что это такое вообще). До конца года сделаю проект на нем, а потом буду более подробно разбираться во фреймворке на курсе. Уже потихоньку начал🙃
❤12🔥2
🎄🎊🎄Всех с наступающим новым годом!!!🎄🎊🎄
Желаю, чтобы в 2026:
• Все задуманные проекты не только запускались, но и отрабатывали без ошибок с первого раза.
• Баги находились до продакшена, а пайплайны не ломались в пятницу вечером.
• Новые технологии давались легко, как синтаксический сахар в Python.
• Ваш код был чистым, как свежевыпавший снег за окном.
Пусть с каждым годом вы становитесь не только профессиональнее, но и здоровее, энергичнее и счастливее - без лишних килограммов на весах и без лишних стрессов.
P.S.
У нас тут за сутки намело почти 70 см снега - такого не помню уже лет 100! ❄️ Если у вас его нет - ловите немного зимней атмосферы на фото. Пусть и у вас будет уютно, тепло и по-новогоднему.
Отличных праздников, ребята! Пусть следующий год будет полным открытий и в коде, и в жизни😼Всем желаемых офферов!😈
Желаю, чтобы в 2026:
• Все задуманные проекты не только запускались, но и отрабатывали без ошибок с первого раза.
• Баги находились до продакшена, а пайплайны не ломались в пятницу вечером.
• Новые технологии давались легко, как синтаксический сахар в Python.
• Ваш код был чистым, как свежевыпавший снег за окном.
Пусть с каждым годом вы становитесь не только профессиональнее, но и здоровее, энергичнее и счастливее - без лишних килограммов на весах и без лишних стрессов.
P.S.
У нас тут за сутки намело почти 70 см снега - такого не помню уже лет 100! ❄️ Если у вас его нет - ловите немного зимней атмосферы на фото. Пусть и у вас будет уютно, тепло и по-новогоднему.
Отличных праздников, ребята! Пусть следующий год будет полным открытий и в коде, и в жизни😼Всем желаемых офферов!😈
❤10🎉7☃2🎅1
Так, пока совсем не забыл как все было в курсе "Добрый, добрый Python ООП - обучающий курс от Сергея Балакирева" - оставляю отзыв:
"""""""""""""""""""""""""""""""
Этот курс я начал проходить еще 3 года назад, не помню почему забросил, но это было зря. Лучше бы завершил его раньше)
Теория:
Объясняется крайне хорошо. Информация в видео-формате, а в текстовом дублируется на личном сайте. Сам не люблю смотреть, а больше читать, но все же в первом случае немного больше инфы и тонкостей рассказывается, рекомендую такой способ поглощения инфы. Много тем разобрано и хорошо пояснено. Не хватает про мета-классы(раз дата-классы были затронуты), возможно в будущем добавиться, но в текстовом формате есть уже на сайте.
Практика:
Достаточно много задач по написанию кода. Для сложных есть видео-разборы на ютубе. Частенько задачи в теме стоят не по порядку увеличения сложности. Забавляли задачи с пометкой "Relax" - здесь никогда не угадаешь будешь ты отдыхать или сидеть на горячем кресле в процессе решения). Тесты с несколькими вариантами ответа та еще боль) Заставляет напрягаться. Но полученных знаний вполне хватает. Если нет - пересмотрите видео еще раз. Местами не хватало(лично мне) простеньких задач на изучение новой темы, иногда сразу рвались с места в карьер.
В общем и целом:
У меня это не первая теория+практика по ОПП, проходил раньше, но давно. Здесь решил восполнить знания. Однако большую часть своего времени я пытался понять что от меня хотят в задачах😅Нет, дело не в условиях и их формулировках(многие почему-то хейтят Сергея за это). Голова отказывалась думать в нужном направлении, наверно больше привык к функциональному стилю программирования и переучиваться сложновато было. А когда решил очередной подвиг, то понимаешь что тут тебе изложено всё по полочкам, иногда кажется что даже слишком сильно.
Рекомендую ли проходить?
Одноздачно да!) Классный курс с отличной теорией и необходимой по объему практикой, с повторением прошлых тем. Так же после прохождения добавите к себе в проекты: Систему обращения по сети, Крестики-нолики, Сапера, Морской бой😈
p.s.
Если вдруг вы не знаете как работает односвязный/двусвязный список, то хочешь не хочешь, точно научишься этому.😂
"""""""""""""""""""""""""""""""
Так же еще нашел парочку неплохих курсов по ООП, но надеюсь я туда не сорвусь, т.к. теперь на очереди Джанго. Вчера все-таки сел за него, 4 часа как будто испарились в небытие😑, а сделал как будто бы нифига.😕Т.к. в данный момент я просто пробегаюсь и вспоминаю, но выходит какая-то каша. В одном мете так пишут, во втором по другому, ИИ-шка вообще говорит третье. Пока что какая-то лабуда, т.к. изучаю не по курсу, а по сборной солянки из разных источников.
Но да ладно, что-то накалякаю, потом покажу этого уродца вам😅
"""""""""""""""""""""""""""""""
Этот курс я начал проходить еще 3 года назад, не помню почему забросил, но это было зря. Лучше бы завершил его раньше)
Теория:
Объясняется крайне хорошо. Информация в видео-формате, а в текстовом дублируется на личном сайте. Сам не люблю смотреть, а больше читать, но все же в первом случае немного больше инфы и тонкостей рассказывается, рекомендую такой способ поглощения инфы. Много тем разобрано и хорошо пояснено. Не хватает про мета-классы(раз дата-классы были затронуты), возможно в будущем добавиться, но в текстовом формате есть уже на сайте.
Практика:
Достаточно много задач по написанию кода. Для сложных есть видео-разборы на ютубе. Частенько задачи в теме стоят не по порядку увеличения сложности. Забавляли задачи с пометкой "Relax" - здесь никогда не угадаешь будешь ты отдыхать или сидеть на горячем кресле в процессе решения). Тесты с несколькими вариантами ответа та еще боль) Заставляет напрягаться. Но полученных знаний вполне хватает. Если нет - пересмотрите видео еще раз. Местами не хватало(лично мне) простеньких задач на изучение новой темы, иногда сразу рвались с места в карьер.
В общем и целом:
У меня это не первая теория+практика по ОПП, проходил раньше, но давно. Здесь решил восполнить знания. Однако большую часть своего времени я пытался понять что от меня хотят в задачах😅Нет, дело не в условиях и их формулировках(многие почему-то хейтят Сергея за это). Голова отказывалась думать в нужном направлении, наверно больше привык к функциональному стилю программирования и переучиваться сложновато было. А когда решил очередной подвиг, то понимаешь что тут тебе изложено всё по полочкам, иногда кажется что даже слишком сильно.
Рекомендую ли проходить?
Одноздачно да!) Классный курс с отличной теорией и необходимой по объему практикой, с повторением прошлых тем. Так же после прохождения добавите к себе в проекты: Систему обращения по сети, Крестики-нолики, Сапера, Морской бой😈
p.s.
Если вдруг вы не знаете как работает односвязный/двусвязный список, то хочешь не хочешь, точно научишься этому.😂
"""""""""""""""""""""""""""""""
Так же еще нашел парочку неплохих курсов по ООП, но надеюсь я туда не сорвусь, т.к. теперь на очереди Джанго. Вчера все-таки сел за него, 4 часа как будто испарились в небытие😑, а сделал как будто бы нифига.😕Т.к. в данный момент я просто пробегаюсь и вспоминаю, но выходит какая-то каша. В одном мете так пишут, во втором по другому, ИИ-шка вообще говорит третье. Пока что какая-то лабуда, т.к. изучаю не по курсу, а по сборной солянки из разных источников.
Но да ладно, что-то накалякаю, потом покажу этого уродца вам😅
👍4🔥1
Как-то так👆выглядит текущий проект на Django😶
Решил делать по одному источнику, дабы не путаться. В итоге, с выбором я прогадал. Изначально просмотрев заголовки тем и прочтя первые из них показалось все неплохо выглядит, т.к. опыт написания на Джанго есть, но он подзабыт. Думаю повторю и хотя бы азы вспомню.
Начал делать: Создал проект, приложение, форму, модель, пару вьюшек, прописал url-пути, чтоб это всё работало. А дальше понеслось🫠 А давайте после 1/5 части установим DRF, напишем сериализатор, подготовим файл для бота в ТГ, API, Celery, Docker.
А дальше продолжается обучение Django, без дрф. Модели поста, его представление, шаблоны, пользователь(CRUD), пароль, отправка почты, права доступа и т.д. и т.п. Зачем такие перескоки - я не понимаю. Но если это пропустить и пойти дальше, то уже будет не совсем понятно😐И вот думаю стоит ли это закончить или нет.
К чему вообще это? Сейчас много инфы в интернете. Выбирайте, смотрите, проверяйте. Но как быть тем, для кого это новый материал🤔🤔🤔
Решил делать по одному источнику, дабы не путаться. В итоге, с выбором я прогадал. Изначально просмотрев заголовки тем и прочтя первые из них показалось все неплохо выглядит, т.к. опыт написания на Джанго есть, но он подзабыт. Думаю повторю и хотя бы азы вспомню.
Начал делать: Создал проект, приложение, форму, модель, пару вьюшек, прописал url-пути, чтоб это всё работало. А дальше понеслось🫠 А давайте после 1/5 части установим DRF, напишем сериализатор, подготовим файл для бота в ТГ, API, Celery, Docker.
А дальше продолжается обучение Django, без дрф. Модели поста, его представление, шаблоны, пользователь(CRUD), пароль, отправка почты, права доступа и т.д. и т.п. Зачем такие перескоки - я не понимаю. Но если это пропустить и пойти дальше, то уже будет не совсем понятно😐И вот думаю стоит ли это закончить или нет.
К чему вообще это? Сейчас много инфы в интернете. Выбирайте, смотрите, проверяйте. Но как быть тем, для кого это новый материал🤔🤔🤔
🤔4🥴2👍1