什么是 mixin 以及它为什么有用?
在 Python 编程中,Mark Lutz 提到了术语 < em>混合。 我来自 C/C++/C# 背景,之前从未听说过这个术语。 什么是混音?
阅读这个例子(我有链接到,因为它很长),我假设这是使用多重继承来扩展类而不是正确的子类化的情况。 这是正确的吗?
为什么我想这样做而不是将新功能放入子类中? 就此而言,为什么混合/多重继承方法比使用组合更好?
mixin 与多重继承的区别是什么? 这只是语义问题吗?
In Programming Python, Mark Lutz mentions the term mixin. I am 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 have linked to because it is quite long), I am presuming it is 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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(18)
mixin 是一种特殊的多重继承。 使用 mixins 主要有两种情况:
对于第一个示例,请考虑 werkzeug 的请求和响应系统。 我可以通过以下方式创建一个普通的旧请求对象:
如果我想添加接受标头支持,我会这样做
如果我想创建一个支持接受标头、etag、身份验证和用户代理支持的请求对象,我可以这样做:
区别很微妙,但在上面的示例中,mixin 类并不是独立存在的。 在更传统的多重继承中,
AuthenticationMixin
(例如)可能更像Authenticator
。 也就是说,该类可能被设计为独立的。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:
The difference is subtle, but in the above examples, the mixin classes weren't made to stand on their own. In more traditional multiple inheritance, the
AuthenticationMixin
(for example) would probably be something more likeAuthenticator
. That is, the class would probably be designed to stand on its own.首先,您应该注意 mixins 仅存在于多重继承语言中。 您无法在 Java 或 C# 中进行 mixin。
基本上,mixin 是一种独立的基本类型,为子类提供有限的功能和多态共振。 如果您在 C# 中思考,请考虑一个您不必实际实现的接口,因为它已经实现了; 您只需继承它并从其功能中受益。
Mixin 的范围通常很窄,并且不打算扩展。
[编辑——至于为什么:]
既然你问了,我想我应该解释为什么。 最大的好处是您不必一遍又一遍地自己做。 在 C# 中,mixin 受益最大的地方可能是 Disposal 模式。 每当您实现 IDisposable 时,您几乎总是希望遵循相同的模式,但最终您会编写并重写相同的基本代码,但有细微的变化。 如果有一个可扩展的 Disposal mixin,您可以节省大量额外的打字时间。
[编辑2——回答你的其他问题]
是的。 mixin 和标准多重继承之间的区别只是语义问题; 具有多重继承的类可能会利用 mixin 作为多重继承的一部分。
mixin 的要点是创建一个可以通过继承“混合”到任何其他类型的类型,而不影响继承类型,同时仍然为该类型提供一些有益的功能。
再次考虑一个已经实现的接口。
我个人不使用 mixin,因为我主要使用不支持它们的语言进行开发,所以我很难想出一个像样的例子来提供“啊哈!”的感觉。 属于你的时刻。 但我会再试一次。 我将使用一个人为的示例——大多数语言已经以某种方式提供了该功能——但这将有望解释如何创建和使用 mixins。 如下:
假设您有一个类型,您希望能够与 XML 进行序列化。 您希望该类型提供一个“ToXML”方法,该方法返回一个包含带有该类型数据值的 XML 片段的字符串,以及一个“FromXML”方法,该方法允许该类型从字符串中的 XML 片段重建其数据值。 同样,这是一个人为的示例,因此您可能使用文件流或语言运行时库中的 XML Writer 类...无论如何。 重点是您希望将对象序列化为 XML 并从 XML 获取一个新对象。
此示例中的另一个重要点是您希望以通用方式执行此操作。 您不想为每个要序列化的类型实现“ToXML”和“FromXML”方法,您需要一些通用方法来确保您的类型能够执行此操作并且它可以正常工作。 您想要代码重用。
如果您的语言支持它,您可以创建 XmlSerialized mixin 来为您完成工作。 该类型将实现 ToXML 和 FromXML 方法。 它将使用某种对示例来说并不重要的机制,能够从与它混合的任何类型收集所有必要的数据,以构建 ToXML 返回的 XML 片段,并且当 FromXML 是时,它同样能够恢复该数据。叫。
就这样。 要使用它,任何需要序列化为 XML 的类型都必须从 XmlSerialized 继承。 每当您需要序列化或反序列化该类型时,您只需调用 ToXML 或 FromXML 即可。 事实上,由于 XmlSerialized 是一种成熟的类型和多态性,因此您可以想象构建一个对原始类型一无所知的文档序列化程序,仅接受 XmlSerialized 类型的数组。
现在想象一下将此场景用于其他事情,例如创建一个 mixin 以确保每个混合它的类都记录每个方法调用,或者创建一个 mixin 为混合它的类型提供事务性。这个列表可以继续下去。
如果您只是将 mixin 视为一个小型基本类型,旨在向类型添加少量功能而不影响该类型,那么您就很成功了。
希望。 :)
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.
[edit -- as to why:]
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.
[edit 2 -- to answer your other questions]
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.
I personally don't use mixins since I develop primarily in a language that doesn't support them, so I'm having a really difficult time coming up with a decent example that will just supply that "ahah!" moment for you. But I'll try again. I'm going to use an example that's contrived -- most languages already provide the feature in some way or another -- but that will, hopefully, explain how mixins are supposed to be created and used. Here goes:
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.
Hopefully. :)
这个答案旨在用示例解释混合,它们是:
自包含:简短,不需要知道任何库来理解示例。
Python,而不是其他语言。
可以理解的是,存在来自其他语言(例如 Ruby)的示例,因为该术语在这些语言中更为常见,但这是一个 Python 线程。
它还应考虑有争议的问题:
定义
我还没有看到来自“权威”来源的引用明确说明什么是 Python 中的 mixin。
我已经看到了 mixin 的两种可能的定义(如果它们被认为与其他类似的概念(例如抽象基类)不同),并且人们并不完全同意哪一种是正确的。
不同语言之间的共识可能会有所不同。
定义1:无多重继承
mixin是一个类,该类的某些方法使用了该类中未定义的方法。
因此,该类并不意味着被实例化,而是作为基类。 否则,该实例将具有无法在不引发异常的情况下调用的方法。
一些来源添加的一个约束是该类可能不包含数据,只包含方法,但我不明白为什么这是必要的。 然而在实践中,许多有用的 mixins 没有任何数据,并且没有数据的基类使用起来更简单。
一个经典的示例是仅从
<=
和==
实现所有比较运算符:这个特定示例可以通过 functools.total_ordering() 实现 装饰器,但这里的游戏是重新发明轮子:
定义 2:多重继承
mixin 是一种设计模式,其中基类的某些方法使用它未定义的方法,并且该方法旨在由另一个基类实现,而不是由定义1中的派生类实现。
术语mixin类指的是旨在使用的基类在该设计模式中(TODO 那些使用该方法的人,或那些实现该方法的人?)
确定给定的类是否是 mixin 并不容易:该方法可以仅在派生类上实现,在这种情况下我们回到定义1。你必须考虑作者的意图。
这种模式很有趣,因为可以通过不同的基类选择来重新组合功能:
权威的 Python 出现
在 collections.abc 的官方文档 该文档明确使用术语Mixin 方法。
它指出,如果一个类:
__next__
Iterator
,那么该类将获得一个
__iter__
mixin方法 免费。因此,至少在文档的这一点上,mixin 不需要多重继承,并且与定义 1 一致。
文档当然可能在不同点上存在矛盾,并且其他重要的 Python 库可能是使用其文档中的其他定义。
此页面还使用术语
Set mixin
,它清楚地表明像Set
和Iterator
这样的类可以称为 Mixin 类。在其他语言中
Ruby:mixin 显然不需要多重继承,正如主要参考书中提到的那样,例如 Ruby 编程 和 Ruby 编程语言
C++:设置
=0
的虚拟
方法是纯虚拟方法。定义1与抽象类(具有纯虚方法的类)的定义一致。
该类无法实例化。
定义 2 可以通过虚拟继承实现:来自两个派生类的多重继承
This answer aims to explain mixins with examples that are:
self-contained: short, with no need to know any libraries to understand the example.
in Python, not in other languages.
It is understandable that there were examples from other languages such as Ruby since the term is much more common in those languages, but this is a Python thread.
It shall also consider the controversial question:
Definitions
I have yet to see a citation from an "authoritative" source clearly saying what is a mixin in Python.
I have seen 2 possible definitions of a mixin (if they are to be considered as different from other similar concepts such as abstract base classes), and people don't entirely agree on which one is correct.
The consensus may vary between different languages.
Definition 1: no multiple inheritance
A mixin is a class such that some method of the class uses a method which is not defined in the class.
Therefore the class is not meant to be instantiated, but rather serve as a base class. Otherwise the instance would have methods that cannot be called without raising an exception.
A constraint which some sources add is that the class may not contain data, only methods, but I don't see why this is necessary. In practice however, many useful mixins don't have any data, and base classes without data are simpler to use.
A classic example is the implementation of all comparison operators from only
<=
and==
:This particular example could have been achieved via the
functools.total_ordering()
decorator, but the game here was to reinvent the wheel:Definition 2: multiple inheritance
A mixin is a design pattern in which some method of a base class uses a method it does not define, and that method is meant to be implemented by another base class, not by the derived like in Definition 1.
The term mixin class refers to base classes which are intended to be used in that design pattern (TODO those that use the method, or those that implement it?)
It is not easy to decide if a given class is a mixin or not: the method could be just implemented on the derived class, in which case we're back to Definition 1. You have to consider the author's intentions.
This pattern is interesting because it is possible to recombine functionalities with different choices of base classes:
Authoritative Python occurrences
At the official documentatiton for collections.abc the documentation explicitly uses the term Mixin Methods.
It states that if a class:
__next__
Iterator
then the class gets an
__iter__
mixin method for free.Therefore at least on this point of the documentation, mixin does not not require multiple inheritance, and is coherent with Definition 1.
The documentation could of course be contradictory at different points, and other important Python libraries might be using the other definition in their documentation.
This page also uses the term
Set mixin
, which clearly suggests that classes likeSet
andIterator
can be called Mixin classes.In other languages
Ruby: Clearly does not require multiple inheritance for mixin, as mentioned in major reference books such as Programming Ruby and The Ruby programming Language
C++: A
virtual
method that is set=0
is a pure virtual method.Definition 1 coincides with the definition of an abstract class (a class that has a pure virtual method).
That class cannot be instantiated.
Definition 2 is possible with virtual inheritance: Multiple Inheritance from two derived classes
我认为它们是使用多重继承的一种有纪律的方式 - 因为最终 mixin 只是另一个 python 类,它(可能)遵循有关称为 mixin 的类的约定。
我对管理你称之为 Mixin 的东西的约定的理解是,Mixin:
object
(在 Python 中),这样它就限制了多重继承的潜在复杂性,并且通过限制您必须查看的位置(与完整的多重继承相比),可以相当轻松地跟踪程序流程。 它们类似于 ruby 模块。
如果我想添加实例变量(比单一继承允许的灵活性更大),那么我倾向于组合。
话虽如此,我见过名为 XYZMixin 的类确实有实例变量。
I think of them as a disciplined way of using multiple inheritance - because ultimately a mixin is just another python class that (might) follow the conventions about classes that are called mixins.
My understanding of the conventions that govern something you would call a Mixin are that a Mixin:
object
(in Python)That way it limits the potential complexity of multiple inheritance, and makes it reasonably easy to track the flow of your program by limiting where you have to look (compared to full multiple inheritance). They are similar to ruby modules.
If I want to add instance variables (with more flexibility than allowed for by single inheritance) then I tend to go for composition.
Having said that, I have seen classes called XYZMixin that do have instance variables.
我认为之前的回复很好地定义了 MixIns 是什么。 然而,
为了更好地理解它们,将MixIns与抽象类和<进行比较可能会很有用em>接口从代码/实现的角度来看:
1。 抽象类
需要包含一个或多个抽象方法的类
抽象类 可以包含状态(实例变量)和非抽象方法
2。 接口
3。 MixIns
在例如Python中,这些只是约定,因为以上所有内容都被定义为
类
。 然而,抽象类、接口和MixIn的共同特征是它们不应该单独存在,即不应该被实例化。I think previous responses defined very well what MixIns are. However,
in order to better understand them, it might be useful to compare MixIns with Abstract Classes and Interfaces from the code/implementation perspective:
1. Abstract Class
Class that needs to contain one or more abstract methods
Abstract Class can contain state (instance variables) and non-abstract methods
2. Interface
3. MixIns
In e.g. Python these are just conventions, because all of the above are defined as
class
es. However, the common feature of both Abstract Classes, Interfaces and MixIns is that they should not exist on their own, i.e. should not be instantiated.mixin 是多重继承的有限形式。 在某些语言中,向类添加 mixin 的机制与继承的机制略有不同(在语法方面)。
特别是在 Python 上下文中,mixin 是一个父类,它为子类提供功能,但本身并不打算实例化。
你可能会说,“这只是多重继承,而不是真正的 mixin”,因为可能会被混淆为 mixin 的类实际上可以被实例化和使用 - 所以这确实是一种语义上的、非常真实的差异。
多重继承
示例此示例来自文档, 是一个有序计数器:
它从
collections
模块中继承了Counter
和OrderedDict
。Counter
和OrderedDict
都旨在单独实例化和使用。 然而,通过对它们进行子类化,我们可以拥有一个有序的计数器并重用每个对象中的代码。这是重用代码的有效方法,但也可能存在问题。 如果发现其中一个对象存在错误,不小心修复它可能会在子类中产生错误。
Mixin 的示例
Mixin 通常被推广为一种实现代码重用的方法,而不会出现协作多重继承(如 OrderedCounter)可能存在的潜在耦合问题。 当您使用 mixin 时,您使用的功能与数据并不紧密耦合。
与上面的示例不同,mixin 并不打算单独使用。 它提供新的或不同的功能。
例如,标准库在
socketserver
库。在这种情况下,mixin 方法会覆盖 UDPServer 对象定义中的方法以允许并发。
重写的方法似乎是
process_request
,它还提供了另一个方法process_request_thread
。 这是来自源代码:一个人为的示例
这是一个 mixin,主要用于演示目的 - 大多数对象将超越此 repr 的用处:
并且用法将是:
并且用法:
A mixin is a limited form of multiple inheritance. In some languages the mechanism for adding a mixin to a class is slightly different (in terms of syntax) from that of inheritance.
In the context of Python especially, a mixin is a parent class that provides functionality to subclasses but is not intended to be instantiated itself.
What might cause you to say, "that's just multiple inheritance, not really a mixin" is if the class that might be confused for a mixin can actually be instantiated and used - so indeed it is a semantic, and very real, difference.
Example of Multiple Inheritance
This example, from the documentation, is an OrderedCounter:
It subclasses both the
Counter
and theOrderedDict
from thecollections
module.Both
Counter
andOrderedDict
are intended to be instantiated and used on their own. However, by subclassing them both, we can have a counter that is ordered and reuses the code in each object.This is a powerful way to reuse code, but it can also be problematic. If it turns out there's a bug in one of the objects, fixing it without care could create a bug in the subclass.
Example of a Mixin
Mixins are usually promoted as the way to get code reuse without potential coupling issues that cooperative multiple inheritance, like the OrderedCounter, could have. When you use mixins, you use functionality that isn't as tightly coupled to the data.
Unlike the example above, a mixin is not intended to be used on its own. It provides new or different functionality.
For example, the standard library has a couple of mixins in the
socketserver
library.In this case, the mixin methods override the methods in the
UDPServer
object definition to allow for concurrency.The overridden method appears to be
process_request
and it also provides another method,process_request_thread
. Here it is from the source code:A Contrived Example
This is a mixin that is mostly for demonstration purposes - most objects will evolve beyond the usefulness of this repr:
and usage would be:
And usage:
Mixins 是编程中的一个概念,其中类提供功能,但并不意味着用于实例化。 Mixins 的主要目的是提供独立的功能,如果 mixins 本身没有与其他 mixins 的继承并且避免状态,那将是最好的。 在 Ruby 等语言中,有一些直接的语言支持,但对于 Python 则没有。 但是,您可以使用多类继承来执行 Python 中提供的功能。
我观看了此视频http://www.youtube.com/watch?v=v_uKI2NOLEM来了解以下基础知识混合。 对于初学者来说,了解 mixins 的基础知识、它们的工作原理以及实现它们时可能遇到的问题非常有用。
维基百科仍然是最好的:http://en.wikipedia.org/wiki/Mixin
Mixins is a concept in Programming in which the class provides functionalities but it is not meant to be used for instantiation. Main purpose of Mixins is to provide functionalities which are standalone and it would be best if the mixins itself do not have inheritance with other mixins and also avoid state. In languages such as Ruby, there is some direct language support but for Python, there isn't. However, you could used multi-class inheritance to execute the functionality provided in Python.
I watched this video http://www.youtube.com/watch?v=v_uKI2NOLEM to understand the basics of mixins. It is quite useful for a beginner to understand the basics of mixins and how they work and the problems you might face in implementing them.
Wikipedia is still the best: http://en.wikipedia.org/wiki/Mixin
这个概念来自 Steve's Ice Cream,一家由 Steve Herrell 在萨默维尔创立的冰淇淋店1973 年,马萨诸塞州,将混合(糖果、蛋糕等)混合到基本冰淇淋口味(香草、巧克力等)中。 受到 Steve's Ice Cream 的启发,Flavors 编程语言的设计者将这一概念包含在1979 年首次成为一种编程语言,其中 mix-ins 是为增强其他类而设计的小型帮助器类,flavors 是大型独立类。
因此,这个概念的要点是可重用扩展(“可重用”相对于“一次性”;“扩展”相对于“基础”)。 混合类可以是抽象类或具体类,因为混合类具有不完整的接口,而抽象类具有不完整的实现,而具体类具有完整的实现。 混合类可以在单继承中继承,通常用于扩展子类的接口,也可以在多重继承中继承,通常用于扩展超级的实现>-类。
混合类名称通常以“-MixIn”、“-able”或“-ible”为后缀,以强调其性质,就像在 Python 标准库中使用
ThreadingMixIn
和ForkingMixIn 一样
类,以及socketserver
模块的Hashable
、Iterable
、Callable
、Awaitable
、AsyncIterable
和 <collections.abcReversible
类代码>模块。以下是
collections.abc
模块的抽象混合内置类Sized
的示例,用于单继承,用于扩展 sub< 的接口/em> - 使用__len__
特殊方法创建Queue
和Stack
类:以下是具体混合类
LoggingMixIn 的示例
在多重继承中使用,用于扩展具有日志记录功能的内置超级类list
和dict
的实现:The concept comes from Steve’s Ice Cream, an ice cream store founded by Steve Herrell in Somerville, Massachusetts, in 1973, where mix-ins (candies, cakes, etc.) were mixed into basic ice cream flavors (vanilla, chocolate, etc.). Inspired by Steve’s Ice Cream, the designers of the Flavors programming language included the concept in a programming language for the first time in 1979, where mix-ins were small helper classes designed for enhancing other classes, and flavors were large standalone classes.
So the gist of the concept is a reusable extension (’reusable’ as opposed to ‘one-time’; ‘extension’ as opposed to ‘foundation’). A mix-in class can be an abstract class or concrete class since mix-in classes have incomplete interfaces whereas abstract classes have incomplete implementations and concrete classes have complete implementations. A mix-in class can be inherited from in single inheritance, usually for extending the interface of the sub-class, or in multiple inheritance, usually for extending the implementation of the super-class.
Mix-in class names are conventionally suffixed with ‘-MixIn’, ‘-able’, or ‘-ible’ to emphasize their nature, like in the Python standard library with the
ThreadingMixIn
andForkingMixIn
classes of thesocketserver
module, and theHashable
,Iterable
,Callable
,Awaitable
,AsyncIterable
, andReversible
classes of thecollections.abc
module.Here is an example of the abstract mix-in built-in class
Sized
of thecollections.abc
module used in single inheritance for extending the interfaces of the sub-classesQueue
andStack
with the__len__
special method:Here is an example of a concrete mix-in class
LoggingMixIn
used in multiple inheritance for extending the implementations of the built-in super-classeslist
anddict
with logging capability:我认为这里已经有一些很好的解释,但我想提供另一个视角。
在 Scala 中,您可以按照此处所述进行 mixins,但非常有趣的是,mixins 实际上“融合”在一起以创建一种新的类来继承。 本质上,您不是从多个类/mixin 继承,而是生成一种新的类,其中包含要继承的 mixin 的所有属性。 这是有道理的,因为 Scala 基于 JVM,目前不支持多重继承(从 Java 8 开始)。 顺便说一句,这个 mixin 类类型是 Scala 中称为 Trait 的特殊类型。
它以类的定义方式暗示:
NewClass 类扩展了 FirstMixin、SecondMixin 和 ThirdMixin
...
我不确定 CPython 解释器是否做同样的事情(混合类组合),但我不会感到惊讶。 另外,由于具有 C++ 背景,我不会将 ABC 或“接口”称为等同于 mixin —— 这是一个类似的概念,但在使用和实现上有所不同。
I think there have been some good explanations here but I wanted to provide another perspective.
In Scala, you can do mixins as has been described here but what is very interesting is that the mixins are actually 'fused' together to create a new kind of class to inherit from. In essence, you do not inherit from multiple classes/mixins, but rather, generate a new kind of class with all the properties of the mixin to inherit from. This makes sense since Scala is based on the JVM where multiple-inheritance is not currently supported (as of Java 8). This mixin class type, by the way, is a special type called a Trait in Scala.
It's hinted at in the way a class is defined:
class NewClass extends FirstMixin with SecondMixin with ThirdMixin
...
I'm not sure if the CPython interpreter does the same (mixin class-composition) but I wouldn't be surprised. Also, coming from a C++ background, I would not call an ABC or 'interface' equivalent to a mixin -- it's a similar concept but divergent in use and implementation.
也许几个例子会有所帮助。
如果您正在构建一个类并且希望它像字典一样工作,则可以定义所有必要的各种
__ __
方法。 但这有点痛苦。 作为替代方案,您可以只定义一些,并从UserDict.DictMixin
继承(除了任何其他继承之外)(在 py3k 中移至collections.DictMixin
)。 这将具有自动定义字典 api 的所有其余部分的效果。第二个例子:GUI 工具包 wxPython 允许您创建具有多列的列表控件(例如,Windows 资源管理器中的文件显示)。 默认情况下,这些列表相当基本。 您可以添加其他功能,例如通过单击列标题、从 ListCtrl 继承并添加适当的 mixin 来按特定列对列表进行排序的功能。
Perhaps a couple of examples will help.
If you're building a class and you want it to act like a dictionary, you can define all the various
__ __
methods necessary. But that's a bit of a pain. As an alternative, you can just define a few, and inherit (in addition to any other inheritance) fromUserDict.DictMixin
(moved tocollections.DictMixin
in py3k). This will have the effect of automatically defining all the rest of the dictionary api.A second example: the GUI toolkit wxPython allows you to make list controls with multiple columns (like, say, the file display in Windows Explorer). By default, these lists are fairly basic. You can add additional functionality, such as the ability to sort the list by a particular column by clicking on the column header, by inheriting from ListCtrl and adding appropriate mixins.
这不是一个 Python 示例,而是在 D 编程语言 中,术语
mixin
用于引用经常使用的构造一样的方法; 向类中添加一堆东西。在 D 中(顺便说一句,它不执行 MI),这是通过将模板(考虑语法感知和安全的宏,你会接近)插入范围来完成的。 这允许类、结构、函数、模块或任何内容中的一行代码扩展到任意数量的声明。
It's not a Python example but in the D programing language the term
mixin
is used to refer to a construct used much the same way; adding a pile of stuff to a class.In D (which by the way doesn't do MI) this is done by inserting a template (think syntactically aware and safe macros and you will be close) into a scope. This allows for a single line of code in a class, struct, function, module or whatever to expand to any number of declarations.
OP 提到他/她从未听说过 C++ 中的 mixin,也许这是因为它们在 C++ 中被称为好奇重复模板模式 (CRTP)。 另外,@Ciro Santilli 提到 mixin 是通过 C++ 中的抽象基类实现的。 虽然抽象基类可以用来实现 mixin,但它是一种矫枉过正,因为运行时虚函数的功能可以在编译时使用模板来实现,而无需在运行时查找虚表的开销。
CRTP模式在此处有详细描述,
我已将@Ciro Santilli的答案中的python示例转换为C++使用下面的模板类:
编辑:在 ComparableMixin 中添加受保护的构造函数,以便它只能继承而不能实例化。 更新了示例以显示创建 ComparableMixin 对象时受保护的构造函数将如何导致编译错误。
OP mentioned that he/she never heard of mixin in C++, perhaps that is because they are called Curiously Recurring Template Pattern (CRTP) in C++. Also, @Ciro Santilli mentioned that mixin is implemented via abstract base class in C++. While abstract base class can be used to implement mixin, it is an overkill as the functionality of virtual function at run-time can be achieved using template at compile time without the overhead of virtual table lookup at run-time.
The CRTP pattern is described in detail here
I have converted the python example in @Ciro Santilli's answer into C++ using template class below:
EDIT: Added protected constructor in ComparableMixin so that it can only be inherited and not instantiated. Updated the example to show how protected constructor will cause compilation error when an object of ComparableMixin is created.
我建议不要在新的 Python 代码中混合,如果你能找到任何其他方法(例如组合而不是继承,或者只是将猴子修补方法到你自己的类中),那也没什么了不起的努力。
在旧式类中,您可以使用混合作为从另一个类获取一些方法的方式。 但在新风格的世界中,一切,甚至混合,都继承自
object
。 这意味着任何多重继承的使用都会自然地引入 MRO 问题 。有多种方法可以使多重继承 MRO 在 Python 中工作,最显着的是 super() 函数,但这意味着您必须使用 super() 来完成整个类层次结构,并且理解控制流要困难得多。
I'd advise against mix-ins in new Python code, if you can find any other way around it (such as composition-instead-of-inheritance, or just monkey-patching methods into your own classes) that isn't much more effort.
In old-style classes you could use mix-ins as a way of grabbing a few methods from another class. But in the new-style world everything, even the mix-in, inherits from
object
. That means that any use of multiple inheritance naturally introduces MRO issues.There are ways to make multiple-inheritance MRO work in Python, most notably the super() function, but it means you have to do your whole class hierarchy using super(), and it's considerably more difficult to understand the flow of control.
mixin 提供了一种在类中添加功能的方法,即您可以通过将模块包含在所需的类中来与模块中定义的方法进行交互。 虽然 ruby 不支持多重继承,但提供 mixin 作为实现这一点的替代方案。
这是一个示例,解释了如何使用 mixin 实现多重继承。
mixin gives a way to add functionality in a class, i.e you can interact with methods defined in a module by including the module inside the desired class. Though ruby doesn't supports multiple inheritance but provides mixin as an alternative to achieve that.
here is an example that explains how multiple inheritance is achieved using mixin.
我刚刚使用 python mixin 来实现 python milters 的单元测试。 通常,milter 会与 MTA 进行通信,这使得单元测试变得困难。 测试 mixin 会覆盖与 MTA 对话的方法,并创建一个由测试用例驱动的模拟环境。
因此,您采用未修改的 milter 应用程序(例如 spfmilter)并混合 TestBase,如下所示:
然后,在 milter 应用程序的测试用例中使用 TestMilter:
http://pymilter.cvs.sourceforge.net/viewvc/pymilter/pymilter/Milter/test.py?修订版=1.6&视图=标记
I just used a python mixin to implement unit testing for python milters. Normally, a milter talks to an MTA, making unit testing difficult. The test mixin overrides methods that talk to the MTA, and create a simulated environment driven by test cases instead.
So, you take an unmodified milter application, like spfmilter, and mixin TestBase, like this:
Then, use TestMilter in the test cases for the milter application:
http://pymilter.cvs.sourceforge.net/viewvc/pymilter/pymilter/Milter/test.py?revision=1.6&view=markup
也许 ruby 的一个示例可以提供帮助:
您可以包含 mixin
Comparable
并定义一个函数"<=>(other)"
,mixin 提供所有这些函数:它通过调用
<=>(other)
并返回正确的结果来实现此目的。如果两个对象相等,
"instance <=> other"
返回 0;如果instance
大于other
且大于other
,则返回小于 0如果other
更大,则为 0。Maybe an example from ruby can help:
You can include the mixin
Comparable
and define one function"<=>(other)"
, the mixin provides all those functions:It does this by invoking
<=>(other)
and giving back the right result."instance <=> other"
returns 0 if both objects are equal, less than 0 ifinstance
is bigger thanother
and more than 0 ifother
is bigger.粗略总结一下上面的所有精彩答案:
Roughly summarizing all great answers above:
我听说你有 ac# 背景。 因此,.NET 的 mixin 实现可能是一个好的起点。
您可能想查看 codeplex 项目,网址为 http://remix.codeplex.com/
观看语言。 net 研讨会链接以获取概述。 codeplex 页面上的文档还有更多内容。
问候
斯特凡
I read that you have a c# background. So a good starting point might be a mixin implementation for .NET.
You might want to check out the codeplex project at http://remix.codeplex.com/
Watch the lang.net Symposium link to get an overview. There is still more to come on documentation on codeplex page.
regards
Stefan