Python高级编程模式和设计模式

一 装饰器模式

order_sources:source1:on_agreement: "reduce_receivable"on_completion: "reduce_receivable"on_rejection: "none"source2:on_agreement: "none"on_completion: "reduce_receivable"on_rejection: "none"source3:on_agreement: "none"on_completion: "none"on_rejection: "none"
import yaml"""
不同来源执行不同的操作的时候,动态判断进行相应的操作
"""
# 读取配置文件
def load_config(file_path):with open(file_path, 'r') as file:config = yaml.safe_load(file)return config"""装饰器:装饰器是一种用于修改或增强函数行为的工具。
在这个例子中,register_handler 是一个装饰器工厂,它返回一个装饰器。
装饰器工厂:装饰器工厂可以根据传入的参数动态生成装饰器。
这里,register_handler 接受一个 action 参数,并返回一个装饰器,
该装饰器将 action 属性添加到被装饰的函数上
"""
def register_handler(action):def decorator(func):func.action = actionreturn funcreturn decorator# 定义处理函数
@register_handler("reduce_receivable")
def reduce_receivable(order_id):print(f"reduce_receivable receivable for order {order_id}.")@register_handler("none")
def no_action(order_id):print(f"No action11111111 for order {order_id}.")# 处理类
class AfterSalesHandler:def __init__(self, config_file):self.config = load_config(config_file)self.handlers = self._register_handlers()"""动态注册:_register_handlers 方法遍历全局命名空间中的所有对象,查找带有 action 属性的可调用对象,并将它们注册到 handlers 字典中。反射:使用 globals() 获取全局命名空间中的所有对象,并通过 hasattr 和 callable 进行检查,这是 Python 中的一种反射机制"""def _register_handlers(self):handlers = {}for name, func in globals().items():if callable(func) and hasattr(func, 'action'):handlers[func.action] = funcprint("handlers---------", handlers)return handlers"""actions:从配置文件中获取指定订单来源的所有操作映射。action:从操作映射中获取指定操作对应的动作。handler:从注册的处理函数中获取指定动作对应的处理函数。handler(order_id):调用处理函数,并传递订单 ID 作为参数"""def handle_after_sales(self, order_id, order_source, operation):actions = self.config['order_sources'].get(order_source, {})action = actions.get(operation, 'none')handler = self.handlers.get(action, self.nofind_action)print("handler-----------------", handler)handler(order_id)def nofind_action(self, order_id):print(f"No action for order {order_id}.")# 示例调用
if __name__ == "__main__":handler = AfterSalesHandler('../data/OrderAfter.yaml')handler.handle_after_sales('12345-1', 'source1', 'on_agreement')handler.handle_after_sales('12345-2', 'source1', 'on_completion')handler.handle_after_sales('12345-3', 'source1', 'on_rejection')handler.handle_after_sales('12345-4', 'source2', 'on_agreement')handler.handle_after_sales('12345-5', 'source2', 'on_completion')handler.handle_after_sales('12345-6', 'source2', 'on_rejection')handler.handle_after_sales('12345-7', 'source3', 'on_agreement')handler.handle_after_sales('12345-8', 'source3', 'on_completion')handler.handle_after_sales('12345-9', 'source3', 'on_rejection')

二 工厂模式

from abc import ABC, abstractmethod
from dataclasses import dataclass
from enum import Enum
import logginglogger = logging.getLogger(__name__)
logging.basicConfig(level=logging.INFO)@dataclass
class OrderInfo:product: strquantity: intclass OrderSource(Enum):ONLINE = 'online'OFFLINE = 'offline'class OrderCreator(ABC):"""基类用于创建订单"""@abstractmethoddef create_order_instance(self, order_info: OrderInfo) -> str:"""子类必须实现此方法以创建具体的订单实例"""passclass OnlineOrderCreator(OrderCreator):"""用于创建线上订单的类"""def create_order_instance(self, order_info: OrderInfo) -> str:"""实现线上订单的创建逻辑"""logger.info(f"Creating online order: {order_info}")return "OnlineOrder123"class OfflineOrderCreator(OrderCreator):"""用于创建线下订单的类"""def create_order_instance(self, order_info: OrderInfo) -> str:"""实现线下订单的创建逻辑"""logger.info(f"Creating offline order: {order_info}")return "OfflineOrder456"class OrderFactory:"""工厂类用于创建不同的订单创建者"""@staticmethoddef get_creator(source: OrderSource) -> OrderCreator:"""根据来源获取相应的订单创建者实例"""if source == OrderSource.ONLINE:return OnlineOrderCreator()elif source == OrderSource.OFFLINE:return OfflineOrderCreator()else:raise ValueError(f"Invalid order source: '{source.value}'")def create_order_instance(order_info: OrderInfo, source: OrderSource) -> str:"""根据指定的来源创建订单实例"""creator = OrderFactory.get_creator(source)return creator.create_order_instance(order_info)# 使用示例
order_info = OrderInfo(product="Widget", quantity=10)
source = OrderSource.ONLINE
order_id = create_order_instance(order_info, source)
print(f"Order ID: {order_id}")

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/471292.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Oracle ADB 导入 BANK_GRAPH 的学习数据

Oracle ADB 导入 BANK_GRAPH 的学习数据 1. 下载数据2. 导入数据运行 setconstraints.sql 1. 下载数据 访问 https://github.com/oracle-quickstart/oci-arch-graph/tree/main/terraform/scripts,下载, bank_accounts.csvbank_txns.csvsetconstraints.…

985研一学习日记 - 2024.11.14

一个人内耗,说明他活在过去;一个人焦虑,说明他活在未来。只有当一个人平静时,他才活在现在。 日常 1、起床6:00 2、健身2h 3、LeetCode刷了题 动态规划概念 如果某一问题有很多重叠子问题,使用动态规划是最有效的…

1.两数之和-力扣(LeetCode)

题目: 解题思路: 在解决这个问题之前,首先要明确两个点: 1、参数returnSize的含义是返回答案的大小(数目),由于这里的需求是寻找数组中符合条件的两个数,那么当找到这两个数时&#…

【excel】easy excel如何导出动态列

动态也有多重含义:本文将描述两种动态场景下的解决方案 场景一:例如表头第一列固定为动物,且必定有第二列,第二列的表头可能为猫 也可能为狗;这是列数固定,列名不固定的场景; 场景二&#xff1…

〔 MySQL 〕数据类型

目录 1.数据类型分类 2 数值类型 2.1 tinyint类型 2.2 bit类型 2.3 小数类型 2.3.1 float 2.3.2 decimal 3 字符串类型 3.1 char 3.2 varchar 3.3 char和varchar比较 4 日期和时间类型 5 enum和set mysql表中建立属性列: 列名称,类型在后 n…

LlamaIndex

一、大语言模型开发框架 SDK:Software Development Kit,它是一组软件工具和资源的集合,旨在帮助开发者创建、测试、部署和维护应用程序或软件。 所有开发框架(SDK)的核心价值,都是降低开发、维护成本。 大语言模型开发框架的价值,是让开发者可以更方便地开发基于大语言…

【FFmpeg】FFmpeg 函数简介 ③ ( 编解码相关函数 | FFmpeg 源码地址 | FFmpeg 解码器相关 结构体 和 函数 )

文章目录 一、FFmpeg 解码器简介1、解码流程分析2、FFmpeg 编解码器 本质3、FFmpeg 编解码器 ID 和 名称 二、FFmpeg 解码器相关 结构体 / 函数1、AVFormatContext 结构体2、avcodec_find_decoder 函数 - 根据 ID 查找 解码器3、avcodec_find_decoder_by_name 函数 - 根据 名称…

Linux——GPIO输入输出裸机实验

学习了正点原子Linux环境下的GPIO的输入输出的裸机实验学习,现在进行一下小结: 启动文件start.S的编写 .global _start .global _bss_start _bss_start:.word __bss_start.global _bss_end _bss_end:.word __bss_end_start:/*设置处理器进入SVC模式*/m…

zabbix搭建钉钉告警流程

目录 🌤️zabbix实验规划 🌤️zabbix实验步骤 📑1 使用钉钉添加一个自定义的机器人 ​ 📑2在zabbix-server上编写钉钉信息发送脚本,设置钉钉报警媒介 ☁️ 设置钉钉报警媒介​编辑​编辑 ☁️在添加消息模板​编辑​…

Java 多线程(三)—— 死锁

死锁的产生 我们先从简单的死锁最后到难一些的死锁问题开始展开讨论。 首先一个线程,一把锁,因为多次加锁而导致死锁问题,由于Java 的synchronized 实现了可重入锁,因此这个死锁问题就不存在了,意味着当一个线程拥有…

makefile 设置动态库路径参数

目录 一、makefile 动态库相关1.1 Libs 变量1.2 LDFLAGS 变量1.3 二者的作用和区别 二、设置方式2.1 编译时指定库路径2.2 运行时指定库路径 三、测试 一、makefile 动态库相关 1.1 Libs 变量 在 Makefile 中,Libs 通常是一个变量,用于存储链接器&…

Servlet入门 Servlet生命周期 Servlet体系结构

一.Servlet入门 1.Servlet介绍 Servlet (server applet) 是运行在服务端(tomcat)的Java小程序,是sun公司提供一套定义动态资源规范; 从代码层面上来讲Servlet就是一个接口 狭义的Servlet是指Java语言编写的一个接口。 广义的Servlet是指任何实现了这个Servlet接口…

穿越数据迷宫:C++哈希表的奇幻旅程

文章目录 前言📔一、unordered系列关联式容器📕1.1 unordered 容器概述📕1.2 哈希表在 unordered 容器中的实现原理📕1.3 unordered 容器的特点 📔二、unordered_set 和 unordered_map 的基本操作📕2.1 un…

飞牛云fnOS本地部署WordPress个人网站并一键发布公网远程访问

文章目录 前言1. Docker下载源设置2. Docker下载WordPress3. Docker部署Mysql数据库4. WordPress 参数设置5. 飞牛云安装Cpolar工具6. 固定Cpolar公网地址7. 修改WordPress配置文件8. 公网域名访问WordPress 前言 本文旨在详细介绍如何在飞牛云NAS上利用Docker部署WordPress&a…

2023年MathorCup数学建模B题城市轨道交通列车时刻表优化问题解题全过程文档加程序

2023年第十三届MathorCup高校数学建模挑战赛 B题 城市轨道交通列车时刻表优化问题 原题再现: 列车时刻表优化问题是轨道交通领域行车组织方式的经典问题之一。列车时刻表规定了列车在每个车站的到达和出发(或通过)时刻,其在实际…

安全见闻1-5

涵盖了编程语言、软件程序类型、操作系统、网络通讯、硬件设备、web前后端、脚本语言、病毒种类、服务器程序、人工智能等基本知识,有助于全面了解计算机科学和网络技术的各个方面。 安全见闻1 1.编程语言简要概述 C语言:面向过程,适用于系统…

闯关leetcode——3178. Find the Child Who Has the Ball After K Seconds

大纲 题目地址内容 解题代码地址 题目 地址 https://leetcode.com/problems/find-the-child-who-has-the-ball-after-k-seconds/description/ 内容 You are given two positive integers n and k. There are n children numbered from 0 to n - 1 standing in a queue in o…

Java结合ElasticSearch根据查询关键字,高亮显示全文数据。

由于es高亮显示机制的问题。当全文内容过多,且搜索中标又少时,就会出现高亮结果无法覆盖全文。因此需要根据需求手动替换。 1.根据es的ik分词器获取搜索词的分词结果。 es部分: //中文分词解析 post /_analyze {"analyzer":"…

Python——NumPy库的简单用法,超级详细教程使用

一、什么是NumPy库 NumPy:它是python的一个科学计算库函数,它是由c语言编写的 它应用于数据处理、机器学习、图像处理、文件操作等等 二、array函数 这里导入库numpy,命名为np,后面的np都是代表着是numpy函数 array函数表示创建…

【Java语言】String类

在C语言中字符串用字符可以表示,可在Java中有单独的类来表示字符串(就是String),现在我来介绍介绍String类。 字符串构造 一般字符串都是直接赋值构造的,像这样: 还可以这样构造: 图更能直观的…