在Python编程中,Mark Lutz提到了术语mixin。我有C/ c++ / c#的背景,以前没有听说过这个术语。什么是mixin?

从这个例子的字里行间(我链接了这个例子,因为它很长),我假设这是一个使用多重继承来扩展类的情况,而不是适当的子类化。这样对吗?

为什么我要这样做,而不是把新功能放到一个子类?就此而言,为什么混合/多重继承方法会比使用组合更好呢?

mixin与多重继承的区别是什么?这只是语义上的问题吗?


当前回答

我认为之前的回答很好地定义了mixin是什么。然而, 为了更好地理解它们,从代码/实现的角度将mixin与抽象类和接口进行比较可能是有用的:

1. 抽象类

类,该类需要包含一个或多个抽象方法 抽象类可以包含状态(实例变量)和非抽象方法

2. 接口

接口只包含抽象方法(没有非抽象方法和内部状态)

3.mixin

mixin(像接口)不包含内部状态(实例变量) mixin包含一个或多个非抽象方法(与接口不同,它们可以包含非抽象方法)

在例如Python中,这些只是约定,因为上面所有的都被定义为类。然而,抽象类、接口和mixin的共同特征是它们不应该独立存在,也就是说不应该被实例化。

其他回答

Mixin提供了一种在类中添加功能的方法,即您可以通过将模块包含在所需的类中来与模块中定义的方法进行交互。虽然ruby不支持多重继承,但提供了mixin作为实现这一目标的替代方案。

下面是一个示例,说明如何使用mixin实现多重继承。

module A    # you create a module
    def a1  # lets have a method 'a1' in it
    end
    def a2  # Another method 'a2'
    end
end

module B    # let's say we have another module
    def b1  # A method 'b1'
    end
    def b2  #another method b2
    end
end

class Sample    # we create a class 'Sample'
    include A   # including module 'A' in the class 'Sample' (mixin)
    include B   # including module B as well

    def S1      #class 'Sample' contains a method 's1'
    end
end

samp = Sample.new    # creating an instance object 'samp'

# we can access methods from module A and B in our class(power of mixin)

samp.a1     # accessing method 'a1' from module A
samp.a2     # accessing method 'a2' from module A
samp.b1     # accessing method 'b1' from module B
samp.b2     # accessing method 'a2' from module B
samp.s1     # accessing method 's1' inside the class Sample

Mixins是编程中的一个概念,其中类提供功能,但并不用于实例化。Mixins的主要目的是提供独立的功能,最好是Mixins本身没有与其他Mixins的继承,并且避免状态。在Ruby等语言中,有一些直接的语言支持,但对于Python则没有。但是,您可以使用多类继承来执行Python中提供的功能。

我看了这个视频http://www.youtube.com/watch?v=v_uKI2NOLEM来了解mixin的基础知识。对于初学者来说,了解mixin的基础知识、它们的工作原理以及在实现它们时可能遇到的问题是非常有用的。

维基百科仍然是最好的:http://en.wikipedia.org/wiki/Mixin

也许举几个例子会有所帮助。

如果您正在构建一个类,并且希望它像字典一样工作,那么您可以定义所有必要的__ __方法。但这有点麻烦。作为一种替代方法,您可以只定义一些,并从UserDict继承(除了任何其他继承)。DictMixin(移动到集合。py3k中的DictMixin)。这将自动定义字典api的所有其余部分。

第二个例子:GUI工具包wxPython允许您创建具有多列的列表控件(例如,在Windows资源管理器中显示的文件)。默认情况下,这些列表相当基本。您可以添加额外的功能,例如通过单击列标题按特定列对列表进行排序的功能,可以从ListCtrl继承并添加适当的mixins。

我认为之前的回答很好地定义了mixin是什么。然而, 为了更好地理解它们,从代码/实现的角度将mixin与抽象类和接口进行比较可能是有用的:

1. 抽象类

类,该类需要包含一个或多个抽象方法 抽象类可以包含状态(实例变量)和非抽象方法

2. 接口

接口只包含抽象方法(没有非抽象方法和内部状态)

3.mixin

mixin(像接口)不包含内部状态(实例变量) mixin包含一个或多个非抽象方法(与接口不同,它们可以包含非抽象方法)

在例如Python中,这些只是约定,因为上面所有的都被定义为类。然而,抽象类、接口和mixin的共同特征是它们不应该独立存在,也就是说不应该被实例化。

mixin是一种特殊的多重继承。使用mixin的主要情况有两种:

您希望为类提供大量可选特性。 你想在很多不同的类中使用一个特定的特性。

对于第一个例子,考虑werkzeug的请求和响应系统。我可以这样创建一个普通的request对象:

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

区别是微妙的,但是在上面的例子中,mixin类并不是独立存在的。在更传统的多重继承中,AuthenticationMixin(例如)可能更像Authenticator。也就是说,这个类可能被设计成独立存在的。