Что такое миксин и почему они полезны?

Чтобы изменить значение tag на 2 и tag1 на 3, используя XMLStarlet :

xmlstarlet ed \
  -u '/root/tag' -v 2 \
  -u '/root/tag1' -v 3 \
  new.xml

Использование ввода образца:

xmlstarlet ed \
  -u '/root/tag' -v 2 \
  -u '/root/tag1' -v 3 \
  <<<'12'

... испускается как выход:



  2
  3

840
задан Aaron Hall 25 March 2016 в 15:16
поделиться

6 ответов

Смешивание является специальным видом множественного наследования. Существует две основных ситуации, где mixins используются:

  1. Вы хотите обеспечить много дополнительных функций для класса.
  2. Вы хотите использовать одну конкретную функцию в большом количестве различных классов.

Для примера номера один, рассмотрите запрос werkzeug и система ответа . Я могу сделать простой объект запроса путем высказывания:

from werkzeug import BaseRequest

class Request(BaseRequest):
    pass

, Если бы я хочу добавить, принимают поддержку заголовка, я сделал бы это

from werkzeug import BaseRequest, AcceptMixin

class Request(AcceptMixin, BaseRequest):
    pass

, Если бы я хотел выполнить запрос возразить, что поддержки принимают заголовки, завершающие теги, аутентификацию и поддержку агента пользователя, то я мог сделать это:

from werkzeug import BaseRequest, AcceptMixin, ETagRequestMixin, UserAgentMixin, AuthenticationMixin

class Request(AcceptMixin, ETagRequestMixin, UserAgentMixin, AuthenticationMixin, BaseRequest):
    pass

различие является тонким, но в вышеупомянутых примерах, смесительные классы не были сделаны стоять самостоятельно. В более традиционном множественном наследовании, AuthenticationMixin (например), вероятно, было бы что-то больше как Authenticator. Таким образом, класс был бы, вероятно, разработан для положения самостоятельно.

637
ответ дан dalore 26 March 2016 в 01:16
поделиться

Возможно, несколько примеров помогут.

при создании класса и Вы хотите, чтобы он действовал как словарь, можно определить все различное __ __ необходимые методы. Но это - что-то вроде боли. Как альтернатива, можно просто определить некоторых и наследоваться (в дополнение к любому другому наследованию) от UserDict.DictMixin (перемещенный в collections.DictMixin в py3k). Это будет иметь эффект автоматического определения всей остальной части API словаря.

А второй пример: инструментарий GUI wxPython позволяет Вам делать средства управления списком с несколькими столбцами (как, скажем, дисплей файла в Windows Explorer). По умолчанию эти списки являются довольно основными. Можно добавить дополнительную функциональность, такую как способность отсортировать список по конкретному столбцу путем нажатия на заголовок столбца, путем наследования ListCtrl и добавления соответствующего mixins.

8
ответ дан John Fouhy 26 March 2016 в 01:16
поделиться

Возможно, пример от рубина может помочь:

можно включать смешивание Comparable и определить одну функцию "<=>(other)", смешивание обеспечивает все те функции:

<(other)
>(other)
==(other)
<=(other)
>=(other)
between?(other)

Это делает это путем вызова <=>(other) и возвращения правильного результата.

"instance <=> other" возвраты 0, если оба объекта равны, меньше чем 0, если instance больше, чем other и больше чем 0, если other больше.

6
ответ дан Georg Schölly 26 March 2016 в 01:16
поделиться

Я отговорил бы от соединения-ins в новом коде Python, если можно найти какой-либо другой путь вокруг этого (такой как composition-instead-of-inheritance или просто исправляющие обезьяну методы в собственные классы), который не является намного большим усилием.

В классах старого стиля Вы могли использовать соединение-ins в качестве способа захватить несколько методов от другого класса. Но в модернизированном мире все, даже соединение - в, наследовалось от object. Это означает, что любое использование множественного наследования естественно представляет выпуски .

MRO

существуют способы сделать множественное наследование работой MRO в Python, прежде всего супер () функция, но это означает, что необходимо сделать целую иерархию классов, использующую супер (), и значительно более трудно понять поток управления.

10
ответ дан bobince 26 March 2016 в 01:16
поделиться

Во-первых, необходимо отметить, что mixins только существуют на языках множественного наследования. Вы не можете сделать смешивания в Java или C#.

В основном, смешивание является автономным базовым типом, который обеспечивает ограниченную функциональность и полиморфный резонанс для дочернего класса. Если Вы думаете в C#, думаете об интерфейсе, который Вы не должны на самом деле реализовывать, потому что он уже реализован; Вы просто наследовались ему и преимущество от его функциональности.

Mixins являются обычно узкими в объеме и не предназначенные, чтобы быть расширенными.

[редактирование - относительно почему:]

я предполагаю, что должен обратиться, почему, так как Вы спросили. Большое преимущество - то, что Вы не должны делать этого сами много раз. В C# самое большое место, где смешивание могло извлечь выгоду, могло бы быть от шаблон Распоряжения . Каждый раз, когда Вы реализуете IDisposable, Вы почти всегда хотите следовать за тем же шаблоном, но Вы заканчиваете тем, что писали и переписали тот же абсолютный код с незначительными изменениями. Если бы было растяжимое смешивание Распоряжения, то Вы могли бы сохранить себя большой дополнительный ввод.

[редактируют 2 - для ответа на другие вопросы]

, Что разделяет смешивание от множественного наследования? Это - просто вопрос семантики?

Да. Различием между смешиванием и стандартным множественным наследованием является просто вопрос семантики; класс, который имеет множественное наследование, мог бы использовать смешивание как часть того множественного наследования.

точка смешивания должна создать тип, который может быть "смешан в" к любому другому типу через наследование, не влияя на наследовавшийся тип, все еще предлагая некоторую выгодную функциональность для того типа.

Снова, думайте об интерфейсе, который уже реализован.

я лично не использую mixins, так как я разрабатываю, прежде всего, на языке, который не поддерживает их, таким образом, мне действительно тяжело придумывать достойный пример, который просто предоставит это "ahah!" момент для Вас. Но я попробую еще раз. Я собираюсь использовать пример, который это изобрело - большинство языков уже обеспечивает функцию так или иначе - но это, надо надеяться, объяснит, как mixins, как предполагается, создаются и используются. Здесь идет:

предположим у Вас есть тип, который Вы хотите смочь сериализировать к и от XML. Вы хотите, чтобы тип предоставил метод "ToXML", который возвращает строку, содержащую фрагмент XML со значениями данных типа и "FromXML", который позволяет типу восстанавливать свои значения данных от фрагмента XML в строке. Снова, это - изобретенный пример, поэтому возможно, Вы используете поток файла или Класс для записи XML от библиотеки времени выполнения Вашего языка... без разницы. Дело в том, что Вы хотите сериализировать свой объект к XML и вернуть новый объект от XML.

другой важный момент в этом примере - то, что Вы хотите сделать это универсальным способом. Вы не хотите должными быть реализовывать "ToXML" и метод "FromXML" для каждого типа, который Вы хотите сериализировать, Вы хотите некоторые универсальные средства обеспечения, что Ваш тип сделает это, и это просто работает. Вы хотите повторное использование кода.

, Если Ваш язык поддерживал его, Вы могли бы создать XmlSerializable mixin, чтобы сделать Вашу работу для Вас. Этот тип реализовал бы ToXML и методы FromXML. Это было бы, с помощью некоторого механизма, это не важно для примера, быть способным к сбору всех необходимых данных из любого типа, что это смешано в с создать фрагмент XML, возвращенный ToXML, и это было бы одинаково способно к восстановлению тех данных, когда FromXML называют.

И..именно. Для использования его у Вас был бы любой тип, который должен быть сериализирован к XML, наследовались XmlSerializable. Каждый раз, когда необходимо было сериализировать или десериализовать тот тип, Вы просто назовете ToXML или FromXML. На самом деле, так как XmlSerializable является абсолютным типом и полиморфный, Вы могли очевидно создать сериализатор документа, который ничего не знает о Вашем исходном типе, принимая только, скажем, массив типов XmlSerializable.

Теперь предполагают использовать этот сценарий для других вещей, как создание смешивания, которое гарантирует, что каждый класс, который смешивает его в журналах каждый вызов метода или смешивание, которое предоставляет transactionality типу, который смешивает его в. Список может продолжиться и на.

, Если Вы просто думаете о смешивании как о небольшом базовом типе, разработанном для добавления небольшого количества функциональности к типу, иначе не влияя на тот тип, затем Вы являетесь золотыми.

, Надо надеяться. :)

214
ответ дан Randolpho 26 March 2016 в 01:16
поделиться
  • 1
    Я не делаю неправильно... Я сделал это три раза... Я подтвердил с OK и закрыл окна переменной окружения прежде, чем сделать снимки экрана, и я открыл новое cmd право после изменяющегося ПУТИ и нажимающий хорошо, и я вновь открыл окно переменной окружения только для того, чтобы сделать снимок экрана. Я не вижу то, что я могу сделать неправильно. Отзовитесь эхом %PATH % только отображает Системный ПУТЬ. – Millemila 22 January 2014 в 10:14

Это не пример Python, но в D программирование языка , термин mixin используется для обращения к используемому почти такому же пути конструкции; добавление груды материала к классу.

В D (который между прочим не делает MI) это сделано путем вставки шаблона (думайте синтаксически осведомленные и безопасные макросы, и Вы будете близки) в объем. Это допускает одну строку кода в классе, структуре, функции, модуле или безотносительно расшириться до любого количества объявлений.

7
ответ дан BCS 26 March 2016 в 01:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: