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

Python设计模式:克隆模式

1. 什么是克隆模式

克隆模式的核心思想是通过复制一个已有的对象(原型)来创建一个新的对象(克隆)。这种方式可以避免重复的初始化过程,从而提高效率。克隆模式通常涉及以下几个方面:

  1. 原型对象:一个已经存在的对象,作为克隆的基础。
  2. 克隆方法:用于复制原型对象的具体方法,通常实现为一个 clone 方法。
  3. 深拷贝与浅拷贝
    • 浅拷贝:创建一个新对象,但不复制嵌套对象的引用。新对象与原对象共享嵌套对象。
    • 深拷贝:创建一个新对象,并递归地复制所有嵌套对象,确保新对象与原对象完全独立。

克隆模式在许多开发场景中都非常有用,以下是一些常见的应用场景:

  1. 图形编辑器:用户可能需要创建多个相似的图形对象(如圆形、矩形等),使用克隆模式可以快速复制现有图形,避免重复的初始化过程。
  2. 游戏开发:在游戏中,克隆模式可以用于创建多个相似的游戏角色或物体,例如创建多个相同类型的敌人或道具。
  3. 文档处理:在文本编辑器或文档处理软件中,用户可能需要插入多个相似格式的段落或文本块,通过克隆模式可以快速复制现有段落,保持格式一致性。
  4. 配置管理:在应用程序中,配置对象可能需要被多次使用。通过克隆模式,可以创建配置对象的副本,以便在不同的上下文中使用,而不需要重新加载或初始化配置。
  5. 状态恢复:在某些应用中,可能需要保存对象的状态并在需要时恢复。克隆模式可以帮助创建对象的快照,以便在后续操作中恢复到之前的状态。
  6. 原型设计模式:克隆模式是原型设计模式的一部分,适用于需要创建大量相似对象的场景。
  7. 数据处理:在数据处理和分析应用中,克隆模式可以用于创建数据记录的副本,以便在处理过程中进行修改而不影响原始数据。

2. 浅拷贝与深拷贝

创建一个 Person 类,该类包含多种属性,包括基本数据类型(如整数、字符串、浮点数)和嵌套对象(如列表和字典)。具体属性如下:

  • name:字符串类型,表示人的名字。
  • age:整数类型,表示人的年龄。
  • height:浮点数类型,表示人的身高。
  • hobbies:列表类型,表示人的爱好(嵌套对象)。
  • address:字典类型,表示人的地址信息(嵌套对象)。
import copyclass Person:def __init__(self, name, age, height, hobbies, address):self.name = name          # 字符串self.age = age            # 整数self.height = height      # 浮点数self.hobbies = hobbies    # 嵌套对象(列表)self.address = address    # 嵌套对象(字典)# 创建一个原始对象
original = Person(name="Alice",age=30,height=5.5,hobbies=["Reading", "Traveling"],address={"city": "New York", "zip": "10001"}
)# 使用浅拷贝创建一个新对象
shallow_copied = copy.copy(original)# 使用深拷贝创建一个新对象
deep_copied = copy.deepcopy(original)# 修改原始对象的基本数据类型属性
original.age = 35
original.height = 6.0# 修改原始对象的嵌套对象
original.hobbies.append("Cooking")
original.address["city"] = "Los Angeles"# 输出结果
print("Original:")
print(f"Name: {original.name}, Age: {original.age}, Height: {original.height}")
print(f"Hobbies: {original.hobbies}, Address: {original.address}")print("\nShallow Copied:")
print(f"Name: {shallow_copied.name}, Age: {shallow_copied.age}, Height: {shallow_copied.height}")
print(f"Hobbies: {shallow_copied.hobbies}, Address: {shallow_copied.address}")print("\nDeep Copied:")
print(f"Name: {deep_copied.name}, Age: {deep_copied.age}, Height: {deep_copied.height}")
print(f"Hobbies: {deep_copied.hobbies}, Address: {deep_copied.address}")
Original:
Name: Alice, Age: 35, Height: 6.0
Hobbies: ['Reading', 'Traveling', 'Cooking'], Address: {'city': 'Los Angeles', 'zip': '10001'}Shallow Copied:
Name: Alice, Age: 30, Height: 5.5
Hobbies: ['Reading', 'Traveling', 'Cooking'], Address: {'city': 'New York', 'zip': '10001'}Deep Copied:
Name: Alice, Age: 30, Height: 5.5
Hobbies: ['Reading', 'Traveling'], Address: {'city': 'New York', 'zip': '10001'}

浅拷贝与深拷贝的表现

  1. 基本数据类型
    • 在浅拷贝和深拷贝的情况下,基本数据类型的属性(如 ageheight)是独立的。修改原始对象的这些属性不会影响克隆对象的相应属性。
  2. 嵌套对象
    • 浅拷贝:对于 hobbies 列表和 address 字典,浅拷贝会创建一个新的 Person 对象,但嵌套对象的引用仍然指向原始对象中的嵌套对象。因此,修改原始对象的嵌套对象会影响到浅拷贝对象。
    • 深拷贝:对于 hobbies 列表和 address 字典,深拷贝会创建一个新的 Person 对象,并递归地复制所有嵌套对象。因此,修改原始对象的嵌套对象不会影响到深拷贝对象。
  • 原始对象ageheight 属性被修改,显示为 356.0
  • 浅拷贝对象ageheight 属性保持不变,仍然是 305.5。但是,hobbies 列表的内容反映了原始对象的变化,因为它们共享同一个列表对象。
  • 深拷贝对象ageheight 属性也保持不变,hobbies 列表和 address 字典的内容与原始对象的变化无关,保持了克隆时的状态。

3. 例子 1:图形编辑器中的克隆模式

在实际开发中,克隆模式常用于图形编辑器等应用程序中。在这些应用程序中,用户可能需要创建多个相似的图形对象(如圆形、矩形等),而这些对象的属性可能会有所不同。使用克隆模式可以简化对象的创建过程,提高效率。
将创建一个 Circle 类,表示一个圆形对象。该类将包含圆心坐标、半径和颜色等属性,并提供克隆功能。

import copyclass Circle:def __init__(self, x, y, radius, color):self.x = x                # 圆心的 x 坐标self.y = y                # 圆心的 y 坐标self.radius = radius      # 半径self.color = color        # 颜色def clone(self):"""克隆方法,使用深拷贝"""return copy.deepcopy(self)def __str__(self):return f"Circle(x={self.x}, y={self.y}, radius={self.radius}, color='{self.color}')"# 创建一个原始圆形对象
original_circle = Circle(x=10, y=20, radius=5, color="red")# 使用克隆方法创建一个新对象
cloned_circle = original_circle.clone()# 修改克隆对象的属性
cloned_circle.x = 15
cloned_circle.color = "blue"# 输出结果
print("Original Circle:", original_circle)  # 输出: Circle(x=10, y=20, radius=5, color='red')
print("Cloned Circle:", cloned_circle)      # 输出: Circle(x=15, y=20, radius=5, color='blue')
  • x:表示圆心的 x 坐标,类型为整数。
  • y:表示圆心的 y 坐标,类型为整数。
  • radius:表示圆的半径,类型为浮点数。
  • color:表示圆的颜色,类型为字符串。
  • clone 方法:该方法使用 copy.deepcopy() 来创建圆形对象的克隆,确保新对象与原对象完全独立。
  • 创建一个原始圆形对象 original_circle,然后使用 clone 方法创建一个克隆对象 cloned_circle
  • 修改克隆对象的属性后,输出原始对象和克隆对象的属性,观察它们的变化。

优点

  • 提高效率:通过克隆现有对象,用户可以快速创建多个相似的图形,避免重复的初始化过程。
  • 简化管理:克隆模式使得对象的管理更加简单,用户可以轻松地修改克隆对象的属性,而不影响原始对象。

4. 例子 2:文本编辑器中的克隆模式

在实际开发中,克隆模式也常用于文本编辑器等应用程序中。在这些应用程序中,用户可能需要创建多个相似的文本格式对象(如段落、标题等),而这些对象的属性可能会有所不同。使用克隆模式可以简化对象的创建过程,提高效率。
将创建一个 Paragraph 类,表示一个段落对象。该类将包含文本内容、字体大小、颜色和对齐方式等属性,并提供克隆功能。

import copyclass Paragraph:def __init__(self, text, font_size, color, alignment):self.text = text                  # 文本内容self.font_size = font_size        # 字体大小self.color = color                # 颜色self.alignment = alignment        # 对齐方式def clone(self):"""克隆方法,使用深拷贝"""return copy.deepcopy(self)def __str__(self):return f"Paragraph(text='{self.text}', font_size={self.font_size}, color='{self.color}', alignment='{self.alignment}')"# 创建一个原始段落对象
original_paragraph = Paragraph(text="This is a sample paragraph.",font_size=12,color="black",alignment="left"
)# 使用克隆方法创建一个新对象
cloned_paragraph = original_paragraph.clone()# 修改克隆对象的属性
cloned_paragraph.text = "This is a cloned paragraph."
cloned_paragraph.font_size = 14
cloned_paragraph.color = "blue"
cloned_paragraph.alignment = "center"# 输出结果
print("Original Paragraph:", original_paragraph)  # 输出: Paragraph(text='This is a sample paragraph.', font_size=12, color='black', alignment='left')
print("Cloned Paragraph:", cloned_paragraph)      # 输出: Paragraph(text='This is a cloned paragraph.', font_size=14, color='blue', alignment='center')
  • text:表示段落的文本内容,类型为字符串。
  • font_size:表示段落的字体大小,类型为整数。
  • color:表示段落的颜色,类型为字符串。
  • alignment:表示段落的对齐方式,类型为字符串(如 “left”、“center”、“right”)。
  • clone 方法:该方法使用 copy.deepcopy() 来创建段落对象的克隆,确保新对象与原对象完全独立。

优点

  • 提高效率:通过克隆现有对象,用户可以快速创建多个相似的段落,避免重复的初始化过程。
  • 简化管理:克隆模式使得对象的管理更加简单,用户可以轻松地修改克隆对象的属性,而不影响原始对象。

相关文章:

Python设计模式:克隆模式

1. 什么是克隆模式 克隆模式的核心思想是通过复制一个已有的对象(原型)来创建一个新的对象(克隆)。这种方式可以避免重复的初始化过程,从而提高效率。克隆模式通常涉及以下几个方面: 原型对象&#xff1a…...

【工具】在 Visual Studio 中使用 Dotfuscator 对“C# 类库(DLL)或应用程序(EXE)”进行混淆

在 Visual Studio 中使用 Dotfuscator 进行混淆 Dotfuscator 是 Visual Studio 自带的混淆工具(Dotfuscator Community Edition,简称 CE)。它可以混淆 C# 类库(DLL)或应用程序(EXE)&#xff0c…...

积分赛——获取环境温度

设计要求 从DS18B20温度传感器上获取环境温度,并将其温度值显示到数码管上(保留两位小数)。 当“S4”定义为发送按键,按键S4按下时,串口向PC端发送当前采集的温度值; 串口发送格式: Temp:26.…...

LogicFlow获取锚点数据的自定义key并添加的连接的Edge边数据中

1、重写 PolylineEdgeModel 类(其它 EdgeModel 都可以) class CustomNetWorkNodeEdge extends PolylineEdge { } class CustomNetWorkNodeEdgeModel extends PolylineEdgeModel {getData() {const data super.getData();//获取开始锚点自定义属性添加到…...

【python中级】解压whl文件内容

【python中级】解压whl文件内容 1.背景2.解压1.背景 【python中级】关于whl文件的说明 https://blog.csdn.net/jn10010537/article/details/146979236 补充以上博客: 在 旧版 setuptools 中(< v58),如果想生成 .whl,必须先pip install 安装 wheel 三方包! pip inst…...

Xilinx系列FPGA实现HDMI2.1视频收发,支持8K@60Hz分辨率,提供2套工程源码和技术支持

目录 1、前言工程概述免责声明 2、相关方案推荐我已有的所有工程源码总目录----方便你快速找到自己喜欢的项目我已有的4K/8K视频处理解决方案我已有的FPGA图像处理方案 3、详细设计方案设计框图硬件设计架构本HDMI2.1性能参数8K视频输入源Video PHY ControllerHDMI 2.1 Receive…...

如何把网页文章转为pdf保存

fnF12调出右边网页端的控制台 在下面输入代码 1、转CSDN上的文章 (function(){ use strict;var articleBox $("div.article_content");articleBox.removeAttr("style");var head_str ""; var foot_str ""; var olde…...

开源可视化大屏go-view前后端安装

一、后端安装 下载代码 git clone https://gitee.com/MTrun/go-view-serve修改配置 cd go-view-serve/ # 修改application-dev.yml的数据库文件地址 vi ./src/main/resources/application-dev.ymlapplication-dev.yml spring:datasource:driver-class-name: org.sqlite.JDB…...

eventEmitter实现

没有做任何异常处理,简单模拟实现 事件对象的每一个事件都对应一个数组 /*__events {"事件1":[cb1,cb2],"事件2":[cb3,cb4],"事件3":[...],"事件4":[...],};*/class E{__events {};constructor(){}//注册监听回调on(type , callbac…...

自然语言处理|如何用少样本技术提升低资源语言处理?

一、引言 在全球化的背景下&#xff0c;自然语言处理&#xff08;NLP&#xff09;技术取得了显著进展&#xff0c;为人们的生活和工作提供了便利。然而&#xff0c;大多数 NLP 研究和应用集中在少数高资源语言上&#xff0c;如英语和中文。据统计&#xff0c;全球存在超过 700…...

系统安全——文件监控-FileMonitor

namespace FileSystemWatcherDemo {public partial class Form1 : Form{ public Form1(){InitializeComponent();UsingFileSystemWatcher();} /// <summary>/// 使用FileSystemWatcher方法/// </summary>void UsingFileSystemWatcher(){//6.2//FileSystemWa…...

07-01-自考数据结构(20331)- 排序-内部排序知识点

内部排序算法是数据结构核心内容,主要包括插入类(直接插入、希尔)、交换类(冒泡、快速)、选择类(简单选择、堆)、归并和基数五大类排序方法。 知识拓扑 知识点介绍 直接插入排序 定义:将每个待排序元素插入到已排序序列的适当位置 算法步骤: 从第二个元素开始遍历…...

Unity:平滑输入(Input.GetAxis)

目录 1.为什么需要Input.GetAxis&#xff1f; 2. Input.GetAxis的基本功能 3. Input.GetAxis的工作原理 4. 常用参数和设置 5. 代码示例&#xff1a;用GetAxis控制角色移动 6. 与Input.GetAxisRaw的区别 7.如何优化GetAxis&#xff1f; 1.为什么需要Input.GetAxis&…...

【AI学习】MCP的简单快速理解

最近&#xff0c;AI界最火热的恐怕就是MCP了。作为一个新的知识点&#xff0c;学习的开始&#xff0c;先摘录一些信息&#xff0c;从发展历程、通俗介绍到具体案例&#xff0c;这样可以快速理解MCP。 MCP发展历程 来自i陆三金 Anthropic 开发者关系负责人 Alex Albert&#…...

单机快速部署开源、免费的分布式任务调度系统——DolphinScheduler

看了DolphinScheduler的介绍&#xff0c;不知道有没有引起你的兴趣&#xff0c;有没有想要上手体验一番呢。本文则主要为大家介绍DolphinScheduler的单机部署方式&#xff0c;方便大家快速体验。 环境准备 需要Java环境&#xff0c;这是一个老生常谈的问题&#xff0c;关于Ja…...

Vue3命名规范指南

在 Vue 3 中&#xff0c;遵循一致的命名规范可以提高代码的可读性和维护性。以下是常见的命名规范和实践建议&#xff1a; 1. 组件命名 PascalCase&#xff08;大驼峰式&#xff09; 单文件组件&#xff08;.vue 文件&#xff09;和组件引用时推荐使用 PascalCase&#xff0c;便…...

【大模型系列篇】大模型基建工程:基于 FastAPI 自动构建 SSE MCP 服务器

今天我们将使用FastAPI来构建 MCP 服务器&#xff0c;Anthropic 推出的这个MCP 协议&#xff0c;目的是让 AI 代理和你的应用程序之间的对话变得更顺畅、更清晰。FastAPI 基于 Starlette 和 Uvicorn&#xff0c;采用异步编程模型&#xff0c;可轻松处理高并发请求&#xff0c;尤…...

springcloud configClient获取configServer信息失败导致启动configClient注入失败报错解决

目录 一、问题现象 二、解决方案 三、运行结果 四、代码地址 一、问题现象 springcloud configClient获取configServer信息失败导致启动configClient注入失败 报错堆栈信息 org.springframework.beans.factory.BeanCreationException: Error creating bean with name scop…...

HarmonyOS-ArkUI Rcp模块类关系梳理

前言 本文重点解决的是&#xff0c;按照官网学习路径学习Tcp模块内容时&#xff0c;越看越混乱的问题。仿照官网案例&#xff0c;书写代码时&#xff0c;产生的各种疑惑。比如&#xff0c;类与类之间的关系&#xff0c;各种配置信息究竟有多少&#xff0c;为什么越写越混乱。那…...

26考研——线性表_ 线性表的链式表示_双循环链表(2)

408答疑 文章目录 三、 线性表的链式表示双循环链表单链表与双链表的比较单链表的特点双链表的特点 双链表上基本操作的实现双链表的插入操作双链表的删除操作 双链表的代码实操定义结点创建一个结点带头结点的双链表初始化创建双链表打印双链表查找结点插入结点在指定节点后插…...

大模型如何引爆餐饮与电商行业变革

大模型如何引爆餐饮与电商行业变革&#xff1f; 一、时代背景&#xff1a;大模型重构产业逻辑的底层动力 1. 技术跃迁催生效率革命 2025年&#xff0c;大模型技术迎来"普惠临界点"。李开复在中关村论坛指出&#xff0c;大模型推理成本每年降低10倍&#xff0c;使得…...

基于springboot的考研成绩查询系统(源码+lw+部署文档+讲解),源码可白嫖!

摘要 这些年随着Internet的迅速发展&#xff0c;我们国家和世界都已经进入了互联网大数据时代&#xff0c;计算机网络已经成为了整个社会以及经济发展的巨大动能&#xff0c;考研成绩查询管理事务现在已经成为社会关注的重要内容&#xff0c;因此运用互联网技术来提高考研成绩…...

es自定义ik分词器中文词库实现热更新

基于web地址的方式实现ik分词热更新。 操作系统&#xff1a;win 11 es version&#xff1a;8.6.2 ik version&#xff1a;8.6.2 1、创建web服务&#xff0c;并提供ik查询词库接口 编写分词http url代码&#xff0c;返回自定义分词内容分词词库数据来自业务需求&#xff0c;存…...

OpenStack 卷虚拟机跨租户迁移方案

目标&#xff1a;迁移租户A的卷虚机到租户B 场景&#xff1a;使用卷虚拟机&#xff0c;租户a和b使用相同网络 租户A的操作&#xff1a; 1.记录虚拟机的ip地址&#xff0c;Mac信息&#xff0c; nova interface-list neutron port-show 2.对虚拟机进行关机操作&#xff0c;将…...

添加购物车功能

业务需求&#xff1a; 用户提交三个字段&#xff0c;服务端根据提交的字段判断是菜品还是套餐&#xff0c;根据菜品或者套餐添加购物车表中。 代码实现 RestController Slf4j RequestMapping("/user/shoppingCart") public class ShoppingCartController {Autowired…...

Logo语言的系统监控

Logo语言的系统监控 引言 在信息技术飞速发展的时代&#xff0c;系统监控成为了确保计算机系统和网络平稳运行的重要手段。系统监控不仅可以实时跟踪系统的性能、资源使用情况和安全风险等&#xff0c;还能够在出现问题时及时发出警报&#xff0c;从而避免潜在的故障和损失。…...

Scheme语言的算法

Scheme语言的算法探索 引言 Scheme是一种以表达式为基础的编程语言&#xff0c;属于Lisp家族&#xff0c;因其简洁、灵活的语法而受到广泛关注。Scheme不仅适合教学&#xff0c;还被用于实际应用开发和研究。本文将深入探讨Scheme语言的算法&#xff0c;包括其基本特性、常用…...

Python爬虫第2节-网页基础和爬虫基本原理

目录 一、网页基础 1.1 网页的组成 1.2 网页的结构 1.3 节点树及节点间的关系 1.4 选择器 二、爬虫的基本原理 2.1 爬虫概述 2.2 能抓怎样的数据 2.3 JavaScript 渲染页面 一、网页基础 使用浏览器访问网站时&#xff0c;我们会看到各式各样的页面。你是否思考过&…...

阿里巴巴langengine二次开发大模型平台

阿里巴巴LangEngine开源了&#xff01;支撑亿级网关规模的高可用Java原生AI应用开发框架 - Leepy - 博客园 阿里国际AI应用搭建平台建设之路(上) - 框架篇 基于java二次开发 目前Spring ai、spring ai alibaba 都是java版本的二次基础能力 重要的是前端工作流 如何与 服务端的…...

深度学习中的 Batch 机制:从理论到实践的全方位解析

一、Batch 的起源与核心概念 1.1 批量的中文译名解析 Batch 在深度学习领域标准翻译为"批量"或"批次"&#xff0c;指代一次性输入神经网络进行处理的样本集合。这一概念源自统计学中的批量处理思想&#xff0c;在计算机视觉先驱者Yann LeCun于1989年提出…...