Продолжаем сложные, но интересные объяснения! 😈
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-истами!😄 Складывать строки и числа.
Исходя из последних постов - вы уже знаете, как это сделать.
❓ Как вам такие возможности наследования??? 👇
🔥 — Огонь, приму на вооружение!
🤔 — Знал, но освежил память.
💬 — Есть вопросы в комментарии!