что такое миксины python
Mixin Classes
dejiok on April 19, 2020
Hi, thanks for this exellent video. Do you mind explaining this section of the code..
kbram on June 15, 2020
I am also interested in understanding this code. Can you respond with the link to explain the 19APR2020 comment?
Roy Telles on Aug. 16, 2020
From what I gather by the video’s small comments and looking up the code by line (where needed) this is what I came up with:
In general this method seems to be checking 3 things:
As far as isinstance and hasattr are concerned, these are the tests I ran in a REPL:
As far as why this check needs to be done in general, that’s beyond me, since as of Python 3 everything inherits from the object super class so it appears to me that isinstance(value, object) would always return true. But I was able to find this StackOverflow article about making your code “Python Agnostic” (adhering to both Python 2 and Python 3 syntax). Hope this helps 🙂
Saul on Nov. 11, 2020
To piggyback on Roy’s answer, it seems that in Python 3 this method could have been simplified and written as the following (given that any value that we could reasonably pass in should inherently be an object):
Given this simplification, the next question you might have is: Why not just do the following instead?
This would work but the output would look like the following:
It would be nice if the class allowed us to also reformat the address output so that the final result would like this instead:
There are two classes that inherit from AsDictionaryMixin: Employee and Address. We initiate a call to_dict() on the Employee objects in our main script code found in program.py:
Otherwise, we just print the value in its standard string representation (like we see with the id or name).
It might be interesting to note that we could have changed the condition to look more directly for whether the object in question inherits from AsDictionaryMixin. That code would look like this:
Русские Блоги
Механизм программирования Python Mixin
Mixin Введение
Характеристики
Использование механизма Mixin имеет следующие преимущества:
Множественное наследование
Python поддерживает множественное наследование, то есть класс может наследовать несколько подклассов. Вы можете использовать эту функцию, чтобы легко реализовать миксиновое наследование. В следующем коде классы A и B представляют разные функциональные единицы, а C представляет собой комбинацию функций A и B, так что класс C имеет функции классов A и B.
__bases__
Реализация множественного наследования создаст новый класс. Иногда, когда мы хотим добавить функцию класса B в класс A. во время выполнения, мы также можем использовать функцию метапрограммирования python. Атрибут __bases__ может легко добавить класс в класс A. во время выполнения. Характеристики B следующие:
Фактически, __bases__ также является механизмом наследования, потому что атрибут __bases__ хранит базовый класс класса. Следовательно, множественные методы наследования также могут быть реализованы следующим образом:
Плагин метод
Вышеупомянутые два метода основаны на множественном наследовании и возможности метапрограммирования Python. Однако, когда бизнес нуждается в изменении, требуется новая комбинация функций. Затем необходимо снова изменить базовый класс A, что вызывает проблемы синхронизации, потому что Мы изменили характеристики класса, а не объекта. Поэтому вышеуказанная модификация затронет все модули, которые относятся к этому классу, что довольно опасно. Обычно мы хотим изменить поведение объекта, а не класса. Точно так же мы можем использовать __dict__, чтобы расширить метод объекта.
What is a mixin, and why are they useful?
In «Programming Python», Mark Lutz mentions «mixins». I’m from a C/C++/C# background and I have not heard the term before. What is a mixin?
Reading between the lines of this example (which I’ve linked to because it’s quite long), I’m presuming it’s a case of using multiple inheritance to extend a class as opposed to ‘proper’ subclassing. Is this right?
Why would I want to do that rather than put the new functionality into a subclass? For that matter, why would a mixin/multiple inheritance approach be better than using composition?
What separates a mixin from multiple inheritance? Is it just a matter of semantics?
16 Answers 16
A mixin is a special kind of multiple inheritance. There are two main situations where mixins are used:
For an example of number one, consider werkzeug’s request and response system. I can make a plain old request object by saying:
If I want to add accept header support, I would make that
If I wanted to make a request object that supports accept headers, etags, authentication, and user agent support, I could do this:
First, you should note that mixins only exist in multiple-inheritance languages. You can’t do a mixin in Java or C#.
Basically, a mixin is a stand-alone base type that provides limited functionality and polymorphic resonance for a child class. If you’re thinking in C#, think of an interface that you don’t have to actually implement because it’s already implemented; you just inherit from it and benefit from its functionality.
Mixins are typically narrow in scope and not meant to be extended.
I suppose I should address why, since you asked. The big benefit is that you don’t have to do it yourself over and over again. In C#, the biggest place where a mixin could benefit might be from the Disposal pattern. Whenever you implement IDisposable, you almost always want to follow the same pattern, but you end up writing and re-writing the same basic code with minor variations. If there were an extendable Disposal mixin, you could save yourself a lot of extra typing.
What separates a mixin from multiple inheritance? Is it just a matter of semantics?
Yes. The difference between a mixin and standard multiple inheritance is just a matter of semantics; a class that has multiple inheritance might utilize a mixin as part of that multiple inheritance.
The point of a mixin is to create a type that can be «mixed in» to any other type via inheritance without affecting the inheriting type while still offering some beneficial functionality for that type.
Again, think of an interface that is already implemented.
Suppose you have a type that you want to be able to serialize to and from XML. You want the type to provide a «ToXML» method that returns a string containing an XML fragment with the data values of the type, and a «FromXML» that allows the type to reconstruct its data values from an XML fragment in a string. Again, this is a contrived example, so perhaps you use a file stream, or an XML Writer class from your language’s runtime library. whatever. The point is that you want to serialize your object to XML and get a new object back from XML.
The other important point in this example is that you want to do this in a generic way. You don’t want to have to implement a «ToXML» and «FromXML» method for every type that you want to serialize, you want some generic means of ensuring that your type will do this and it just works. You want code reuse.
If your language supported it, you could create the XmlSerializable mixin to do your work for you. This type would implement the ToXML and the FromXML methods. It would, using some mechanism that’s not important to the example, be capable of gathering all the necessary data from any type that it’s mixed in with to build the XML fragment returned by ToXML and it would be equally capable of restoring that data when FromXML is called.
And.. that’s it. To use it, you would have any type that needs to be serialized to XML inherit from XmlSerializable. Whenever you needed to serialize or deserialize that type, you would simply call ToXML or FromXML. In fact, since XmlSerializable is a fully-fledged type and polymorphic, you could conceivably build a document serializer that doesn’t know anything about your original type, accepting only, say, an array of XmlSerializable types.
Now imagine using this scenario for other things, like creating a mixin that ensures that every class that mixes it in logs every method call, or a mixin that provides transactionality to the type that mixes it in. The list can go on and on.
If you just think of a mixin as a small base type designed to add a small amount of functionality to a type without otherwise affecting that type, then you’re golden.
Что такое mixin и почему они полезны?
В » Программировании Python » Марк Лутц упоминает «миксины». Я из C/C++/С# фона, и я не слышал термин раньше. Что такое миксин?
Читая между строк этого примера (который я связал, потому что он довольно длинный), я предполагаю, что это случай использования множественного наследования для расширения класса, а не для «правильного» подкласса. Это правильно?
Почему я хотел бы сделать это, а не помещать новую функциональность в подкласс? В этом отношении, почему подход смешанного/множественного наследования лучше, чем использование композиции?
Что отличает миксин от множественного наследования? Это просто вопрос семантики?
Вы хотите предоставить множество дополнительных функций для класса. Вы хотите использовать одну конкретную функцию во множестве разных классов.
Например, номер один, рассмотрите систему запроса и ответа werkzeug. Я могу сделать простой старый объект запроса, сказав:
Если я хочу добавить поддержку заголовка Accept, я бы сделал это
Если бы я хотел создать объект запроса, поддерживающий прием заголовков, etags, проверку подлинности и поддержку пользовательского агента, я мог бы сделать это:
Во-первых, вы должны заметить, что mixins существуют только в языках с несколькими наследованиями. Вы не можете использовать mixin в Java или С#.
В принципе, mixin является автономным базовым типом, который обеспечивает ограниченную функциональность и полиморфный резонанс для дочернего класса. Если вы думаете на С#, подумайте о интерфейсе, который вам не нужно реализовывать, поскольку он уже реализован; вы просто наследуете его и извлекаете выгоду из его функциональности.
Микшины, как правило, узкие по охвату и не предназначены для расширения.
Полагаю, мне следует обратиться к тому, почему, поскольку вы спросили. Большим преимуществом является то, что вам не нужно делать это снова и снова. В С# наибольшее место, где мог бы быть использован миксин, можно найти в схеме удаления. Всякий раз, когда вы реализуете IDisposable, вы почти всегда хотите следовать одному и тому же шаблону, но в итоге вы записываете и переписываете один и тот же базовый код с небольшими вариациями. Если бы существовала расширяемая система Disposal mixin, вы могли бы сэкономить много лишнего набора текста.
Что отличает mixin от множественного наследования? Это просто вопрос семантики?
Точкой mixin является создание типа, который может быть «смешанным» с любым другим типом через наследование, не затрагивая тип наследования, при этом предлагая некоторые полезные функции для этого типа.
Снова подумайте о интерфейсе, который уже реализован.
Предположим, что у вас есть тип, который вы хотите сериализовать в и из XML. Вы хотите, чтобы тип предоставлял метод «ToXML», который возвращает строку, содержащую фрагмент XML, с значениями данных этого типа и «FromXML», который позволяет типу восстанавливать свои значения данных из XML-фрагмента в строке. Опять же, это надуманный пример, поэтому, возможно, вы используете поток файлов или класс XML Writer из вашей библиотеки времени исполнения. что угодно. Дело в том, что вы хотите сериализовать свой объект в XML и вернуть новый объект из XML.
Другим важным моментом в этом примере является то, что вы хотите сделать это в общем виде. Вы не хотите внедрять метод «ToXML» и «FromXML» для каждого типа, который вы хотите сериализовать, вам нужны некоторые общие средства обеспечения того, чтобы ваш тип выполнял это, и он просто работает. Вы хотите повторное использование кода.
Если ваш язык поддерживает его, вы можете создать XmlSerializable mixin, чтобы выполнить свою работу за вас. Этот тип будет реализовывать методы ToXML и FromXML. При использовании некоторого механизма, не важного для примера, он мог бы собирать все необходимые данные из любого типа, с которым он смешивался, для создания XML-фрагмента, возвращаемого ToXML, и он также мог бы восстановить эти данные, когда FromXML называется.
И.. что это. Чтобы использовать его, у вас будет любой тип, который должен быть сериализован для XML, наследуемого от XmlSerializable. Всякий раз, когда вам нужно было сериализовать или десериализовать этот тип, вы просто вызываете ToXML или FromXML. На самом деле, поскольку XmlSerializable является полнофункциональным типом и полиморфным, вы могли бы создать сериализатор документов, который ничего не знает о вашем исходном типе, принимая только, скажем, массив XmlSerializable типов.
Теперь представьте, что вы используете этот сценарий для других вещей, например создание mixin, который гарантирует, что каждый класс, который смешивает его в журналах с каждым вызовом метода, или mixin, который обеспечивает транзакцию для типа, в котором он находится. Список может продолжаться и на.
Если вы просто думаете о том, что mixin является небольшим базовым типом, предназначенным для добавления небольшого количества функций к типу, не влияя на этот тип, тогда вы золотые.
Что такое миксин и почему они полезны?
В « Программировании Python » Марк Лутц упоминает «миксины». Я из C / C ++ / C # фона, и я не слышал этот термин раньше. Что такое миксин?
Читая между строк этого примера (который я связал, потому что он довольно длинный), я предполагаю, что это случай использования множественного наследования для расширения класса, а не для «правильного» подкласса. Это правильно?
Почему я хотел бы сделать это, а не помещать новую функциональность в подкласс? В этом отношении, почему подход смешанного / множественного наследования лучше, чем использование композиции?
Что отличает миксин от множественного наследования? Это просто вопрос семантики?
Если я хочу добавить поддержку заголовка принять, я бы сделал это
Если бы я хотел создать объект запроса, который поддерживает заголовки принятия, etags, аутентификацию и поддержку агента пользователя, я мог бы сделать это:
Во-первых, вы должны заметить, что миксины существуют только в языках множественного наследования. Вы не можете сделать миксин в Java или C #.
Миксины обычно узкие по объему и не предназначены для расширения.
Что отличает миксин от множественного наследования? Это просто вопрос семантики?
Да. Разница между миксином и стандартным множественным наследованием является лишь вопросом семантики; класс с множественным наследованием может использовать миксин как часть этого множественного наследования.
Смысл mixin состоит в том, чтобы создать тип, который можно «смешать» с любым другим типом посредством наследования, не затрагивая наследующий тип, и в то же время предлагать некоторые полезные функциональные возможности для этого типа.
Опять же, подумайте об интерфейсе, который уже реализован.
Другим важным моментом в этом примере является то, что вы хотите сделать это в общем виде. Вам не нужно реализовывать методы «ToXML» и «FromXML» для каждого типа, который вы хотите сериализовать, вам нужны некоторые общие средства, гарантирующие, что ваш тип будет делать это, и он просто работает. Вы хотите повторного использования кода.
Если ваш язык поддерживает это, вы можете создать миксин XmlSerializable, который сделает вашу работу за вас. Этот тип будет реализовывать методы ToXML и FromXML. Используя некоторый механизм, который не важен для примера, он мог бы собрать все необходимые данные из любого типа, с которым он смешан, для создания фрагмента XML, возвращаемого ToXML, и он был бы в равной степени способен восстанавливать эти данные, когда FromXML называется.
И это все. Чтобы использовать его, вы должны иметь любой тип, который нужно сериализовать, чтобы XML наследовал от XmlSerializable. Когда бы вам ни понадобилось сериализовать или десериализовать этот тип, вы просто вызывали бы ToXML или FromXML. Фактически, поскольку XmlSerializable является полноценным типом и полиморфным, вы могли бы создать сериализатор документов, который ничего не знает о вашем исходном типе, принимая только, скажем, массив типов XmlSerializable.
Теперь представьте, что вы можете использовать этот сценарий для других целей, например, для создания миксина, который гарантирует, что каждый класс, который смешивает его, регистрирует каждый вызов метода, или миксина, который обеспечивает транзакционность для типа, который его смешивает. Список можно продолжать и продолжать.
Если вы просто думаете о миксине как о небольшом базовом типе, предназначенном для добавления небольшого количества функциональности к типу, без какого-либо влияния на этот тип, то вы просто великолепны.