Этот ответ направлен на объяснение mixins примерами, которые:
It также должен рассмотреть спорный вопрос:
Требуется ли множественное наследование или не охарактеризовать mixin?
blockquote>Определения
У меня еще нет чтобы увидеть цитату из «авторитетного» источника, четко говорящего о том, что такое mixin в Python.
Я видел 2 возможных определения mixin (если их следует рассматривать как отличающиеся от других подобных понятий, таких как абстрактные базовые классы), и люди не полностью согласны с тем, какой из них правильный.
Консенсус может различаться между разными языками.
Определение 1: отсутствие множественного наследования
Mixin - это класс, так что в некотором методе класса используется метод, который не определен в классе.
Поэтому класс не предназначен для создания экземпляра, а скорее s как основной класс. В противном случае экземпляр имел бы методы, которые нельзя вызвать без привлечения исключения.
Ограничение, которое добавляют некоторые источники, состоит в том, что класс не может содержать данные, только методы, но я не понимаю, почему это необходимо , На практике, однако, многие полезные миксины не имеют никаких данных, а базовые классы без данных проще использовать.
Классическим примером является реализация всех операторов сравнения только из
<=
и==
:class ComparableMixin(object): """This class has methods which use `<=` and `==`, but this class does NOT implement those methods.""" def __ne__(self, other): return not (self == other) def __lt__(self, other): return self <= other and (self != other) def __gt__(self, other): return not self <= other def __ge__(self, other): return self == other or self > other class Integer(ComparableMixin): def __init__(self, i): self.i = i def __le__(self, other): return self.i <= other.i def __eq__(self, other): return self.i == other.i assert Integer(0) < Integer(1) assert Integer(0) != Integer(1) assert Integer(1) > Integer(0) assert Integer(1) >= Integer(1) # It is possible to instantiate a mixin: o = ComparableMixin() # but one of its methods raise an exception: #o != o
Этот конкретный пример мог быть достигнут с помощью декоратора
functools.total_ordering()
, но игра здесь заключалась в том, чтобы изобрести колесо:import functools @functools.total_ordering class Integer(object): def __init__(self, i): self.i = i def __le__(self, other): return self.i <= other.i def __eq__(self, other): return self.i == other.i assert Integer(0) < Integer(1) assert Integer(0) != Integer(1) assert Integer(1) > Integer(0) assert Integer(1) >= Integer(1)
Определение 2: множественное наследование
Mixin - это шаблон проектирования, в котором какой-либо метод базового класса использует метод, который он не определяет, и этот метод предполагается реализовать другим базовым классом , а не по производному, как в определении 1.
Термин mixin class относится к базовым классам, которые предназначены для использования в этом шаблоне проектирования (TODO те, которые используют этот метод, или те которые его реализуют?)
Нелегко решить, является ли данный класс микшированием или нет: метод может быть просто реализован в производном классе, и в этом случае мы вернемся к определению 1. Вы должны рассмотреть t авторские намерения.
Этот шаблон интересен тем, что можно рекомбинировать функциональные возможности с различными вариантами базовых классов:
class HasMethod1(object): def method(self): return 1 class HasMethod2(object): def method(self): return 2 class UsesMethod10(object): def usesMethod(self): return self.method() + 10 class UsesMethod20(object): def usesMethod(self): return self.method() + 20 class C1_10(HasMethod1, UsesMethod10): pass class C1_20(HasMethod1, UsesMethod20): pass class C2_10(HasMethod2, UsesMethod10): pass class C2_20(HasMethod2, UsesMethod20): pass assert C1_10().usesMethod() == 11 assert C1_20().usesMethod() == 21 assert C2_10().usesMethod() == 12 assert C2_20().usesMethod() == 22 # Nothing prevents implementing the method # on the base class like in Definition 1: class C3_10(UsesMethod10): def method(self): return 3 assert C3_10().usesMethod() == 13
Авторитетные вхождения Python
At официальный документ для collection.abc в документации явно используется термин Методы Mixin .
В нем указано, что если класс:
- реализует
__next__
- наследуется от одного класса
Iterator
, тогда класс получает метод
__iter__
mixin бесплатно.Поэтому, по крайней мере, в этой точке документации, mixin не требует множественного наследования и согласуется с определением 1.
Документация может быть, конечно, противоречивой в разных точках, а другие важные библиотеки Python могут использовать другое определение в своей документации.
На этой странице также используется термин
Set mixin
, в котором четко указано, что такие классы, какSet
иIterator
, могут называются классами Миксина.На других языках
- Ruby: Очевидно, не требуется множественное наследование для mixin, как указано в основных справочниках, таких как Programming Ruby и The Ruby programming Язык
- C ++: метод, который не реализован, является чистым виртуальным методом. Определение 1 совпадает с определением абстрактного класса (класса, который имеет чистый виртуальный метод). Этот класс не может быть создан. Определение 2 возможно с виртуальным наследованием: Множественное наследование от двух производных классов
Чтобы заставить клавиатуру появиться немедленно, вам нужно установить текстовое поле в качестве первого ответчика с помощью следующей строки:
[textField becomeFirstResponder];
Вы можете поместить это в метод viewDidAppear:
.
Предпочтите добавлять первого респондента на основном потоке -
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
DispatchQueue.main.async {
self.textField.becomeFirstResponder()
}
}
Это пригодится, когда представление контроллера представления будет добавлено как подпредставление.