当前位置: 首页 > news >正文

python的mixin设计模式

1.介绍

在 Python 中,mixin 是一种设计模式,它是一个包含了特定功能单元的类,这些功能可以被其他类组合利用,这些功能可以被其他类组合利用,以实现代码的复用和功能扩展。

mixin 类通常不被单独实例化,也不作为其他类的唯一父类,而是通过多重继承与其他类结合使用。子类可以根据需要组合继承不同功能的 mixin 类,从而在不修改源代码的情况下扩展已有类的功能。

mixin 类具有以下特点:

  • 可复用性:包含可重用的方法或属性,可被多个类继承和使用,提高了代码的复用性。
  • 灵活性:能在不修改类层次结构的前提下,动态地为类添加功能,增加了代码的灵活性和可扩展性。
  • 多重继承:一般通过多重继承的方式被其他类使用,允许类具有多种功能,而无需将所有功能集中在一个类中。

例如,假设有一个 LoggerMixin 类用于记录日志功能:

class LoggerMixin:def log(self, message):print(f"Log: {message}")

然后可以定义其他类,并通过继承 LoggerMixin 来获得日志记录功能: 

class MyClass(LoggerMixin):def do_something(self):self.log("Doing something...")

在上述示例中,MyClass 继承了 LoggerMixin 的 log 方法,无需在 MyClass 中重新实现日志记录功能,就可以直接使用该方法。

使用 mixin 类时需要遵循一些原则:

  • 尽量以 mixin 作为类名后缀,以明确其作用。
  • mixin 类实现的功能应单一通用,如果有多个功能,就写多个 mixin 类。
  • 子类不继承 mixin 类也应能初始化成功,mixin 类只是扩展了子类的功能,而不能影响子类的原有功能。

mixin 模式有助于避免多重继承可能导致的“钻石问题”(菱形继承问题)或继承歧义,同时可以提高代码的可维护性和可扩展性,使得代码结构更加清晰和灵活。它在许多 Python 框架和库中都有广泛的应用,例如 Django 框架中就使用了 mixin 来组合不同的功能。

2.实质

mixin 本质上仍然是 Python 的一个类。

mixin 类与普通类的区别主要在于其设计目的和使用方式。普通类通常旨在独立实例化并代表一个完整的对象,而 mixin 类则更侧重于提供特定的功能或行为,以便其他类通过继承来组合和利用这些功能。

例如,一个 LoggingMixin 类可能只包含与日志记录相关的方法,它本身不构成一个完整独立的对象概念,但可以被其他类继承以添加日志功能。

尽管如此,从语法和结构上看,mixin 类和普通类没有本质区别,都遵循 Python 类的定义和行为规则。

3.Django

Django 是一个高级的 Python Web 框架,旨在帮助开发者快速、高效地构建安全和可维护的 Web 应用程序。

Django 遵循了模型-视图-模板(Model-View-Template,MVT)的架构模式。它提供了许多强大的功能和特性,包括:

  1. 数据库管理: 内置了对多种数据库的支持,并提供了一个对象关系映射(Object-Relational Mapping,ORM)系统,使开发者可以通过 Python 代码来操作数据库,而无需编写复杂的 SQL 语句。

  2. 路由系统: 允许开发者方便地定义 URL 与视图函数之间的映射关系。

  3. 表单处理: 提供了方便的方式来创建、验证和处理表单数据。

  4. 模板系统: 支持使用模板语言来生成动态的 HTML 页面。

  5. 后台管理界面: 自动生成一个功能强大的后台管理界面,方便对数据进行管理。

  6. 安全性: 内置了许多安全机制,如防止跨站请求伪造(CSRF)、SQL 注入防护等。

  7. 扩展性: 可以通过安装第三方库和插件来扩展其功能。

例如,如果要创建一个博客应用,使用 Django 可以很容易地定义文章模型、处理文章的创建和展示视图、设计模板,以及设置相关的路由。

总的来说,Django 大大简化了 Web 开发的流程,提高了开发效率,使得开发者能够更专注于业务逻辑的实现,而不必过多关注底层的技术细节。

在 Django 框架中,使用 mixin 来组合不同功能意味着通过创建包含特定功能的类(即 mixin 类),然后让其他相关的类继承这些 mixin 类,从而将这些特定功能添加到继承的类中。

例如,Django 的视图类(View Class)可能会使用 mixin 。假设有一个 LoginRequiredMixin ,它的功能是确保只有登录用户才能访问特定的视图。

然后有一个自定义的视图类 MyView ,如果希望 MyView 具有登录检查的功能,就可以让 MyView 继承 LoginRequiredMixin 以及其他必要的视图类。

这样,MyView 就自动获得了登录检查的功能,而无需在 MyView 中重复编写相关的登录验证代码。

再比如,可能有一个 PermissionMixin 用于处理权限检查,一个 CacheControlMixin 用于控制缓存策略等。通过将这些 mixin 与视图类组合,可以灵活地为视图添加各种不同的附加功能。

这体现了代码复用和功能模块化的原则,使得 Django 框架的视图部分更加灵活、可扩展和易于维护。

 4.拓展

在 Python 中,框架、模式和类是不同层次和范畴的概念,它们有以下的区别和联系:

类(Class)

  • 定义:类是一种用户自定义的数据类型,用于描述具有相同属性和方法的对象的集合。它定义了对象的特征(属性)和行为(方法)。
  • 目的:类的主要目的是对相关的数据和操作进行封装,创建对象的模板。
  • 示例:比如定义一个 Person 类,具有 name 和 age 属性以及 introduce 方法。
    class Person:def __init__(self, name, age):self.name = nameself.age = agedef introduce(self):print(f"我叫{self.name},今年{self.age}岁。")

    模式(Pattern)

  • 定义:模式是在软件开发中经过反复验证和总结出来的解决特定问题的通用方案和设计思路。
  • 目的:模式的目的是提供一种可重复使用的、经过优化的解决方案,帮助开发者更高效地设计和构建软件。
  • 示例:常见的设计模式如单例模式(确保一个类只有一个实例存在)、工厂模式(用于创建对象)、观察者模式(对象间的一种一对多依赖关系)等。
  • 模式可以在类的设计和实现中应用,以优化类的结构和功能。
  • 框架通常基于各种设计模式构建,并提供了一系列的类和模块,开发者通过使用和扩展这些类来构建应用。
  • 定义:框架是一个提供了一系列工具、库和规范的应用程序开发平台。它为开发特定类型的应用提供了基本的架构和基础设施。
  • 目的:框架的目的是简化和加速应用程序的开发过程,开发者在框架的基础上进行定制和扩展来实现具体的业务逻辑。
  • 示例:Django 是一个用于 Web 开发的框架,Flask 也是一个轻量级的 Web 框架;Scrapy 是用于爬虫开发的框架。

用一个盖房子的例子来通俗地说明这三者的关系。

就像是盖房子用的各种材料,比如砖头、木材、窗户玻璃等等。每一种材料都有自己的特点(属性)和用途(方法)。比如砖头可以用来砌墙,木材可以用来做房梁。

模式则像是盖房子的一些通用设计方法。比如说,如果要盖一个抗震的房子,可能会有一种特定的结构设计模式;如果要盖一个能节省空间的房子,又会有另一种布局的模式。这些模式不是具体的材料,但告诉你怎么用这些材料来达到更好的效果。

框架就像是一个已经搭好了基本框架的房子毛坯。它有了房子的大致结构,比如已经建好了墙壁、屋顶的框架。你只需要按照这个框架的规则和提供的条件,来进行内部的装修(添加具体的业务逻辑),比如布置房间、安装电器等等,就能很快把房子变成一个能住人的成品。

总结起来就是,类是基础的元素,模式是使用这些元素的好方法,框架则是基于这些方法搭建好的一个初步的整体结构,让你能更方便快捷地完成整个项目。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Android C++系列:Linux线程(四)线程同步
  • 突破4.5K星标!一键转换网页,探索AI赋能的知识新领域
  • 小白一步步实现SSM框架之AOP(自己实现)
  • 直播架构如何设计核心节点和边缘节点
  • ansible安装
  • 人工智能算法工程师(高级)课程1-单类目标识别之人脸检测识别技术MTCNN模型介绍与代码详解
  • 【46 Pandas+Pyecharts | 当当网畅销图书榜单数据分析可视化】
  • 用ssh tunnel的方式设置 AWS DocumentDB 公网访问
  • jvm常用密令、jvm性能优化、jvm性能检测、Java jstat密令使用、Java自带工具、Java jmap使用
  • TensorFlowTTS tts语音合成使用案例;tflite模型转换及加载使用
  • PHP基础语法(一)
  • tomcat的优化
  • verilog bug记录——正点原子spi_drive存在的问题
  • Go语言并发编程-Goroutine调度
  • 51单片机嵌入式开发:12、STC89C52RC 红外解码数码管显示
  • [Vue CLI 3] 配置解析之 css.extract
  • 0x05 Python数据分析,Anaconda八斩刀
  • co.js - 让异步代码同步化
  • crontab执行失败的多种原因
  • css系列之关于字体的事
  • express.js的介绍及使用
  • Javascripit类型转换比较那点事儿,双等号(==)
  • JavaScript 无符号位移运算符 三个大于号 的使用方法
  • jQuery(一)
  • magento2项目上线注意事项
  • mysql_config not found
  • PHP面试之三:MySQL数据库
  • React-Native - 收藏集 - 掘金
  • Redis在Web项目中的应用与实践
  • SQLServer插入数据
  • STAR法则
  • 从setTimeout-setInterval看JS线程
  • 从零搭建Koa2 Server
  • 大主子表关联的性能优化方法
  • 类orAPI - 收藏集 - 掘金
  • 力扣(LeetCode)21
  • 体验javascript之美-第五课 匿名函数自执行和闭包是一回事儿吗?
  • 听说你叫Java(二)–Servlet请求
  • 一天一个设计模式之JS实现——适配器模式
  • Linux权限管理(week1_day5)--技术流ken
  • NLPIR智能语义技术让大数据挖掘更简单
  • Prometheus VS InfluxDB
  • SAP CRM里Lead通过工作流自动创建Opportunity的原理讲解 ...
  • ​插件化DPI在商用WIFI中的价值
  • ### Error querying database. Cause: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException
  • (1) caustics\
  • (11)MSP430F5529 定时器B
  • (20)docke容器
  • (3)STL算法之搜索
  • (3)医疗图像处理:MRI磁共振成像-快速采集--(杨正汉)
  • (libusb) usb口自动刷新
  • (vue)el-cascader级联选择器按勾选的顺序传值,摆脱层级约束
  • (zhuan) 一些RL的文献(及笔记)
  • (计算机网络)物理层
  • (四)docker:为mysql和java jar运行环境创建同一网络,容器互联