В чем разница между миксином и наследованием?
A mix-in - это базовый класс, от которого вы можете наследовать, чтобы обеспечить дополнительную функциональность. Пример псевдокода:
class Mixin:
def complex_method(self):
return complex_functionality(self)
Название «mix-in» указывает, что оно предназначено для смешивания с другим кодом. Таким образом, вывод заключается в том, что вы не будете создавать экземпляр встроенного класса самостоятельно. Следующий объект не имеет данных, и нет смысла создавать его экземпляр для вызова complex_method. (В этом случае вы также можете просто определить функцию вместо класса.)
>>> obj = Mixin()
Часто смешивание используется с другими базовыми классами.
Следовательно, mixins - это подмножество или особый случай наследования.
Преимущества использования надстройки над одиночным наследованием состоят в том, что вы можете написать код для функциональности один раз, а затем использовать одну и ту же функциональность в нескольких разных классах. Недостатком является то, что вам, возможно, придется искать эту функциональность в других местах, отличных от тех, где она используется, поэтому полезно уменьшить этот недостаток, держа его рядом.
Лично я нашел дополнение, необходимое для использования по одиночному наследованию, когда мы тестируем множество одинакового кода, но тестовые случаи создаются на основе их наследования базового случая и единственного способа сохранить Код под рукой (и в том же модуле), не связываясь с номерами покрытия, должен наследоваться от объекта, а дочерние случаи наследуются как от универсальной базы тестовых наборов, так и от пользовательской базы, которая применяется только к ним.
Mixins в сравнении и контрасте с абстрактными базовыми классами
Оба являются формой родительского класса, который не предназначен для создания экземпляра.
A mixin предоставляет функциональные возможности, но не может напрямую его использовать. Пользователь предназначен для использования его через (под) класс.
абстрактный базовый класс предоставляет интерфейс, но без полезной функциональности. Пользователь предназначен для создания функциональности, вызываемой интерфейсом.
class Abstraction(metaclass=abc.ABCMeta):
@abc.abstractmethod
def complex_method(self):
return complex_functionality(self)
Здесь вам запрещено создавать экземпляр этого объекта, поскольку для реализации функциональности с помощью конкретного метода требуется подкласс (хотя вы можете получить доступ к функциональности в пределах super()
):
>>> obj = Abstraction()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class Abstraction with
abstract methods complex_method
В Python некоторые классы в модуле abc
являются примерами родительских классов, которые предоставляют функциональность через наследование и абстрактные интерфейсы, которые должны быть реализованы подклассом. Эти идеи не являются взаимоисключающими.
Резюме
Проще говоря, встраиваемый модуль - это просто базовый класс, который вы не будете создавать самостоятельно, и обычно он используется как вторичный базовый класс в множественном наследовании.