zoukankan      html  css  js  c++  java
  • python mixin到底是什么 django

    1.什么是Mixin

    在面向对象编程中,Mixin是一种类,这种类包含了其他类要使用的方法,但不必充当其他类的父类。其他类是如何获取Mixin中的方法因语言的不同而不同。所以有时候Mixin被描述为'include'(包含)而不是 inheritance(继承)。

    Mixins鼓励代码重用,并且可以用于避免多重继承可能导致(“如钻石问题”)的继承歧义,或者解决一个缺乏对一种语言的多重继承的支持。mixin也可以被看作 实现方法 的接口。 这种模式是强制依赖性反转原理的一个例子。

    2.Mixin来源

    mix-in是一种冰淇淋,提供一些基础口味(香草,巧克力等),在这种基础口味上可以添加其他食品(坚果,小饼干)。Mixin术语由此得来

    3.定义及优点

    Mixins是一种语言概念,允许程序员将一些代码注入到一个类中。Mixin编程是一种软件开发的风格,其中功能单元在一个类中创建,然后与其他类混合。

    mixin类扮演父类的角色,包含其他类想要的功能。 然后,一个子类可以继承或简单地重用此功能,但不能作为专业化的手段。通常,mixin将会将所需的功能导出到子类中,而不会创建一个单一的“is a”关系。 这是mixins和继承的概念之间的重要区别,因为子类仍然可以继承父类的所有功能,但是,不必一定应用关于子对象“作为一种”父语义的语义。


    优点

    1.通过允许多个类使用通用功能,但没有多重继承的复杂语义,为多重继承提供了一种机制.
    2. 代码可重用性:当程序员希望在不同类之间共享功能时,Mixins很有用。 而不是一遍又一遍地重复相同的代码,通用功能可以简单地分组成一个混合,然后继承到需要它的每个类中。
    3.Mixins允许继承和使用只有父类的所需功能,不一定是父类的所有功能.


    4.在python中的应用

    在Python中,SocketServer模块]具有UDPServer类和TCPServer类。它们分别作为UDP和TCP套接字服务器的服务器。 另外,还有两个mixin类:ForkingMixIn和ThreadingMixIn。通常,所有新连接都在相同的过程中处理。 通过使用ThreadingMixIn扩展TCPServer,如下所示:

    class ThreadingTCPServer(ThreadingMixIn, TCPServer):
      pass
    ThreadingMixIn类向TCP服务器添加功能,以便每个新连接创建一个新的线程。或者,使用ForkingMixIn将导致为每个新连接分叉进程。 显然,创建新线程或分支进程的功能作为独立类不是非常有用的。

    在此使用示例中,mixins提供了替代底层功能,而不影响套接字服务器的功能。


    5.在Django项目中的应用

    Django TemplateView的实现代码如下:

    class TemplateView(TemplateResponseMixin, ContextMixin, View):
        """
        A view that renders a template.  This view will also pass into the context
        any keyword arguments passed by the URLconf.
        """
        def get(self, request, *args, **kwargs):
            context = self.get_context_data(**kwargs)
            return self.render_to_response(context)
    可以看到,这个视图‘继承了’TempalteResponseMixin,和ContextMixin以及View。TempalteResponseMixin和ContextMixin实现分别如下:

    class TemplateResponseMixin(object):
        """
        A mixin that can be used to render a template.
        """
        template_name = None
        template_engine = None
        response_class = TemplateResponse
        content_type = None
    
        def render_to_response(self, context, **response_kwargs):
            """
            Returns a response, using the `response_class` for this
            view, with a template rendered with the given context.
    
            If any keyword arguments are provided, they will be
            passed to the constructor of the response class.
            """
            response_kwargs.setdefault('content_type', self.content_type)
            return self.response_class(
                request=self.request,
                template=self.get_template_names(),
                context=context,
                using=self.template_engine,
                **response_kwargs
            )
    
        def get_template_names(self):
            """
            Returns a list of template names to be used for the request. Must return
            a list. May not be called if render_to_response is overridden.
            """
            if self.template_name is None:
                raise ImproperlyConfigured(
                    "TemplateResponseMixin requires either a definition of "
                    "'template_name' or an implementation of 'get_template_names()'")
            else:
                return [self.template_name]

    class ContextMixin(object):
        """
        A default context mixin that passes the keyword arguments received by
        get_context_data as the template context.
        """
    
        def get_context_data(self, **kwargs):
            if 'view' not in kwargs:
                kwargs['view'] = self
            return kwargs
    
    可以看到这两个Mixin实际上只是为了给TemplatesView提供get_context_data和render_to_response两个接口以及其他需要的数据,但这里并不适合把这两个类解释为TemplatesView的父类,而更倾向于解释为提供接口及数据。把这两个类封装成mixin格式可以提高代码的重用性,把这两个类直接设计成函数我认为(个人见解,还 请指正)也是可以的,只不过这样以来就不那么面向对象编程了。所以可以说Mixin应该是一种设计思想,并没有什么独特之处。至于好多类名字中为什么要加上Mixin,这只是为了提高代码的可读性而已。

    以上观点纯属个人观点,还请大家多指出错误,以便及时更改。



  • 相关阅读:
    js获取UserControl (<uc1>)控件ID
    NPOI的使用
    Ajax实现页面后台button click事件无刷新弹窗
    java反射中Class对象详解和类名.class, class.forName(), getClass()区别
    反射的笔记
    MyEclipse异常关闭导致启动不了tomcat的解决方法
    java面试题05
    java面试题04
    Spring笔记03(Spring创建对象的三种方式)
    Spring笔记02(3种加载配置文件的方式)
  • 原文地址:https://www.cnblogs.com/hiveme/p/8194829.html
Copyright © 2011-2022 走看看