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

python设计模式12:状态模式

什么是状态机? 

关键属性: 状态和转换

状态: 系统当前状态

转换:一种状态到另外一种状态的变化。

转换由触发事件或是条件启动。

状态机-状态图

状态机使用场景: 

自动售货机  电梯  交通灯   组合锁  停车计时器  

使用state_machine 模块创建状态机第一步使用@acts_as_state_machine装饰器

@acts_as_state_machine
class Process:

 initial 属性值设置为 True

created = State(initial=True)
waiting = State()
running = State()
terminated = State()
blocked = State()
swapped_out_waiting = State()
swapped_out_blocked = State()

定义转换。在 state_machine 模块中,转换是 Event 类的一个实例。我们使用
参数 from_states 和 to_state 定义可能的转换。
 

wait = Event(from_states=(created,
running,
blocked,
swapped_out_waiting),
to_state=waiting)
run = Event(from_states=waiting,
to_state=running)
terminate = Event(from_states=running,
to_state=terminated)
block = Event(from_states=(running,swapped_out_blocked),
to_state=blocked)
swap_wait = Event(from_states=waiting,
to_state=swapped_out_waiting)
swap_block = Event(from_states=blocked,
to_state=swapped_out_blocked)

 from_states 可以是单个状态,也可以是一组状态(元组)。

 state_machine 模块为我们
提供了 @before 和 @after 装饰器,二者可以分别用于在转换发生之前或之后执行操作。你可以
想象在系统中更新一些对象,或者向某人发送电子邮件或通知。在本例中,操作仅限于打印关于
进程状态更改的信息。

transition() 函数,它接受三个参数:
 process , Process 的一个实例;
 event , Event 的一个实例( wait 、 run 、 terminate 等);
 event_name ,事件的名称。

执行事件时出错,则输出事件的名称。
下面是 transition() 函数的代码:
 

def transition(process, event, event_name):
try:
event()
except InvalidStateTransition as err:
print(f'Error: transition of {process.name}
from {process.current_state} to {event_name} failed')

state_info() 函数显示进程当前(激活)状态的一些基本信息。 


def state_info(process):
print(f'state of {process.name}: {process.current_state}')

在 main() 函数的开头,我们定义了一些字符串常量,它们被作为 event_name 传递。
 

def main():
RUNNING = 'running'
WAITING = 'waiting'
BLOCKED = 'blocked'
TERMINATED = 'terminated'

创建两个 Process 实例并展示它们的初始状态信息。 


p1, p2 = Process('process1'), Process('process2')
[state_info(p) for p in (p1, p2)]

 允许的转换应该与
状态图相关。例如,应该可以从一个运行状态切换到一个阻塞状态,但是不应该从一个阻塞状态
切换到一个运行状态。

from  state_machine   import   (State,Event,acts_as_state_machine,after,before,InvalidStateTransition)@acts_as_state_machine
class Process:created=State(initial=True)  # 创建状态waiting=State() #等待状态running=State()#  运行状态terminated=State()# 停止状态blocked=State() # 阻塞swapper_out_waiting=State()#swapper_out_blocked=State()# 等待状态  转入的状态from_states ,目标状态: to_statewait=Event(from_states=(created,running,blocked,swapper_out_waiting),to_state=waiting)run=Event(from_states=waiting,to_state=running)terminate=Event(from_states=running,to_state=terminated)block=Event(from_states=(running,swapper_out_blocked),to_state=blocked)swap_wait=Event(from_states=waiting,to_state=swapper_out_waiting)swap_block=Event(from_states=blocked,to_state=swapper_out_blocked)def  __init__(self,name):self.name=name@after('wait')def wait_info(self):print(f'{self.name} entered waiting mode')@after('run')def run_info(self):print(f'{self.name} is running')@before('ternimate')def terminate_info(self):print(f"{self.name} terminated")@after('block')def block_info(self):print(f'{self.name} is blocked')@after('swap_wait')def swap_wait_info(self):print(f'{self.name} is swapped out and waiting')@after('swap_block')def swap_block_info(self):print(f'{self.name} is swapped out and blocked')@after('block')def block_info(self):print(f'{self.name} is blocked')@after('swap_wait')def swap_wait_info(self):print(f'{self.name} is swapped out and waiting')@after('swap_block')def swap_block_info(self):print(f'{self.name} is swapped out and blocked')def transition(process,event,event_name):try:event()except  InvalidStateTransition as err:print(f"Error: transaction of {process.name} from  {process.current_state}  to {event_name} failed")# 显示信息def  state_info(process):print(f'state of {process.name}:{process.current_state}')def main():RUNNING='running'WAITING='waiting'BLOCKED='blocked'TERMINATED='terminated'p1,p2=Process('process1'),Process('process2')[state_info(p)  for p in (p1,p2)]print("-------1----------")transition(p1,p1.wait,WAITING)transition(p2,p2.terminate,TERMINATED)[state_info(p) for  p in (p1,p2)]print("------2----------")transition(p1,p1.run,RUNNING)transition(p2,p2.wait,WAITING)[state_info(p) for p in (p1, p2)]print("------3----------")transition(p2, p2.run, RUNNING)[state_info(p) for p in (p1, p2)]print("------4----------")[transition(p,p.block,BLOCKED) for p in (p1,p2)][state_info(p) for p in (p1, p2)]print("------5----------")[transition(p, p.terminate, TERMINATED) for p in (p1, p2)]if __name__=='__main__':main()
state of process1:created
state of process2:created
-------1----------
process1 entered waiting mode
Error: transaction of process2 from  created  to terminated failed
state of process1:waiting
state of process2:created
------2----------
process1 is running
process2 entered waiting mode
state of process1:running
state of process2:waiting
------3----------
process2 is running
state of process1:running
state of process2:running
------4----------
process1 is blocked
process1 is blocked
process2 is blocked
process2 is blocked
state of process1:blocked
state of process2:blocked
------5----------
Error: transaction of process1 from  blocked  to terminated failed
Error: transaction of process2 from  blocked  to terminated failed

相关文章:

python设计模式12:状态模式

什么是状态机? 关键属性: 状态和转换 状态: 系统当前状态 转换:一种状态到另外一种状态的变化。 转换由触发事件或是条件启动。 状态机-状态图 状态机使用场景: 自动售货机 电梯 交通灯 组合锁 停车计时…...

JS对图片尺寸和DPI进行编辑修改(1寸照修改为2寸照)

各种报名都对照片有大小限制&#xff0c;鉴于这种情况&#xff0c;网上搜了后拼凑出了如下代码&#xff0c;用于解决1寸照片修改为2寸照片&#xff0c;同时将DPI修改为300&#xff0c;当然也可以根据自己的情况修改代码&#xff1a; HTML <input type"file" id&…...

EDA实验----四选一多路选择器设计(QuartusII)

目录 一&#xff0e;实验目的 二&#xff0e;实验仪器设备 三&#xff0e;实验原理&#xff1a; 四&#xff0e;实验要求 五&#xff0e;实验内容及步骤 1.实验内容 2.实验步骤 六&#xff0e;实验报告 七.实验过程 1.创建Verilog文件&#xff0c;写代码 2.波形仿真 …...

从windows iso文件中提取install.wim

1、首先从微软官方下载需要的windows镜像 https://www.microsoft.com/zh-cn/software-download/windows10/ 2、在下载的iso文件右键&#xff0c;打开压缩包&#xff0c;在sources文件夹下&#xff0c;应该就可以看到install.wim了。但似乎在最新的win10版本&#xff0c;微软采…...

Python的flask网页编程的GET和POST方法的区别

关于flask网页编程的GET及POST方法之间存在哪些区别问题&#xff0c;我们主要从以下六个关键点予以详细阐述&#xff1a; 首先需要明确的是&#xff0c;GET与POST两种不同类型的HTTP方法所采用的请求模式有所差别。其中&#xff0c;GET方法采用的是基于URL请求的机制&#xff…...

15 # 手写 throttle 节流方法

什么是节流 节流是限制事件触发的频率&#xff0c;当持续触发事件时&#xff0c;在一定时间内只执行一次事件&#xff0c;这个效果跟英雄联盟里的闪现技能释放差不多。 函数防抖关注一定时间连续触发的事件只在最后执行一次&#xff0c;而函数节流侧重于一段时间内只执行一次…...

puzzle(1612)拼单词、wordlegame

目录 拼单词 wordlegame 拼单词 在线play 找出尽可能多的单词。 如果相邻的话&#xff08;在任何方向上&#xff09;&#xff0c;你可以拖拽鼠标从一个字母&#xff08;方格&#xff09;到另一个字母&#xff08;方格&#xff09;。在一个单词中&#xff0c;你不能多次使用…...

【解决方案】pytion 运行时提示 import psutil ModuleNotFoundError: No module named ‘psutil‘

报错原因分析 import psutil ModuleNotFoundError: No module named psutil报错原因分析 当前环境pytion中缺少了psutil包&#xff0c;使用pip命令进行安装 解决方案 pip install psutil...

CSS3 过度效果、动画、多列

一、CSS3过度&#xff1a; CSS3过渡是元素从一种样式逐渐改变为另一种的效果。要实现这一点&#xff0c;必须规定两相内容&#xff1a;指定要添加效果的CSS属性&#xff1b;指定效果的持续时间。如果为指定持续时间&#xff0c;transition将没有任何效果。 <style> div…...

java使用geotools解析矢量数据kml、geojson、shp文件

geotools解析kml、geojson geotools环境准备公共获取属性方法解析kml解析geojson解析shp geotools环境准备 这里使用的是maven引用geotools包&#xff0c;引用geotools包需要添加maven仓库&#xff0c;pom.xml文件如下&#xff1a; <properties><!-- geotools版本 -…...

原生 JS DOM 常用操作大全

DOM DOM文档对象模型 又称为DOM树 DOM树 由文档、元素、节点 组成文档&#xff1a;一个页面就是一个文档&#xff0c;元素&#xff1a;文档中的所有标签都称为元素。DOM中使用Element表示节点&#xff1a;文档中的所有内容&#xff0c;在文档中都是节点&#xff08;标签、属性…...

昇腾CANN 7.0 黑科技:DVPP硬件加速训练数据预处理,友好解决Host CPU预处理瓶颈

在NPU/GPU上进行模型训练计算&#xff0c;为了充分使用计算资源&#xff0c;一般采用批量数据处理方式&#xff0c;因此一般情况下为提升整体吞吐率&#xff0c;batch值会设置的比较大&#xff0c;常见的batch数为256/512&#xff0c;这样一来&#xff0c;对数据预处理处理速度…...

Aria2 任意文件写入漏洞复现

漏洞描述 Aria2 是一款轻量级、多协议、多源下载工具&#xff08;支持 HTTP/HTTPS、FTP、BitTorrent、Metalink&#xff09;&#xff0c;内置 XML-RPC 和 JSON-RPC 接口。 我们可以使用 RPC 接口来操作 aria2 并将文件下载到任意目录&#xff0c;从而造成任意文件写入漏洞。 …...

思维模型 多看效应

本系列文章 主要是 分享 思维模型&#xff0c;涉及各个领域&#xff0c;重在提升认知。越熟悉&#xff0c;越喜欢。 1 多看效应的应用 1.1 多看效应在广告和营销领域的应用 1 可口可乐之歌 可口可乐公司在 20 世纪 60 年代推出了“可口可乐之歌”广告&#xff0c;这个广告通…...

持续集成交付CICD:Jenkins Pipeline与远程构建触发器

目录 一、实验 1.Jenkins Pipeline本地构建触发器 2.Jenkins Pipeline与远程构建触发器&#xff08;第一种方式&#xff09; 3.Jenkins Pipeline与远程构建触发器&#xff08;第二种方式&#xff09; 4.Jenkins Pipeline与远程构建触发器&#xff08;第三种方式&#xff0…...

【无标题(PC+WAP)花卉租赁盆栽绿植类pbootcms站模板

(PCWAP)花卉租赁盆栽绿植类pbootcms网站模板 PbootCMS内核开发的网站模板&#xff0c;该模板适用于盆栽绿植网站等企业&#xff0c;当然其他行业也可以做&#xff0c;只需要把文字图片换成其他行业的即可&#xff1b; PCWAP&#xff0c;同一个后台&#xff0c;数据即时同步&…...

pytorch 学习率衰减策略

##学习率衰减策略 import torch.nn.functional as F import torch import torch.nn as nn import matplotlib.pyplot as plt#初始化模型 class Net(nn.Module):def __init__(self):super(Net, self).__init__()self.conv1 = nn.Conv2d(1, 10, kernel_size=5)self.conv2 = nn.Co…...

Flink SQL -- 概述

1、Flink SQL中的动态表和连续查询 1、动态表&#xff1a; 因为Flink是可以做实时的&#xff0c;数据是在不断的变化的&#xff0c;所以动态表指的是Flink中一张实时变换的表&#xff0c;表中会不断的有新的数据。但是这张表并不是真正的物理表。 2、连续查询&#xff1a; 连续…...

Spring RabbitMQ那些事(1-交换机配置消息发送订阅实操)

目录 一、序言二、配置文件application.yml三、RabbitMQ交换机和队列配置1、定义4个队列2、定义Fanout交换机和队列绑定关系2、定义Direct交换机和队列绑定关系3、定义Topic交换机和队列绑定关系4、定义Header交换机和队列绑定关系 四、RabbitMQ消费者配置五、RabbitMQ生产者六…...

C++动态库

C动态库 动态库文件&#xff08;Dynamic Link Library&#xff0c;DLL&#xff09;是程序在运行时所需要调用的库。静态库文件是程序在编译时所需要调用的库。 1 环境介绍 VS版本&#xff1a;VS2017 编程语言&#xff1a;C 2 功能介绍 使用VS2017项目模板创建C动态库生成…...

LangChain4j聊天记忆存储怎么选?Redis、MySQL、MongoDB、向量库全方案对比与选型指南

LangChain4j聊天记忆存储架构选型指南&#xff1a;从Redis到向量库的深度对比 当构建基于LangChain4j的AI对话系统时&#xff0c;聊天记忆存储方案的选择直接影响着用户体验、系统性能和长期可扩展性。作为架构师&#xff0c;我们需要在内存缓存、关系型数据库、文档数据库和向…...

Chart.js项目实战:物流运输跟踪系统的终极可视化指南

Chart.js项目实战&#xff1a;物流运输跟踪系统的终极可视化指南 【免费下载链接】awesome A curated list of awesome Chart.js resources and libraries 项目地址: https://gitcode.com/GitHub_Trending/awesome/awesome 在当今快节奏的物流行业中&#xff0c;实时数据…...

面试官:聊聊Redis中RDBAOF持久化原理!

Redis 中数据的持久化前言我们知道 Redis 是内存数据库&#xff0c;所有操作都在内存上完成。内存的话&#xff0c;服务器断电&#xff0c;内存上面的数据就会丢失了。这个问题显然是需要解决的。Redis 中引入了持久化来避免数据的丢失&#xff0c;主要有两种持久化的方式 RDB …...

重载 AGV 控制怎么做?这篇 2025 论文把“载荷转移”讲透了

最新 AGV 控制论文解析&#xff1a;20 吨重载 AGV 怎么把“轨迹跟踪”和“车身稳定”一起管起来&#xff1f; 摘要 这次分析一篇 AGV 控制 方向的最新论文&#xff0c;而且和前面讲过的 Pure Pursuit 改进、外部视觉导航、托盘装卸 都不重复。本文选取的是 2025 年发表的论文 《…...

GraphMind:用“搭积木”的思路做的概念绘图神器

分享一个特别有意思的脑洞&#xff0c;最新打磨出的 SKILL——文本AI绘图引擎&#xff08;graph_mind&#xff09;。说起这个idea&#xff0c;得把时间拨回2018年的夏天。当时我在中科院自动化所跟着余老师实习&#xff0c;我们构造过一个“位置信息生成图片”的算法。时过境迁…...

客服机器人回答错误可自动撤回?智能 Agent 功能详解 + 消息撤回,发错答案快速补救?

在电商客服场景中&#xff0c;智能客服机器人已经成为企业降本增效的核心工具。然而&#xff0c;机器人再智能&#xff0c;也难免出现回答偏差、答非所问或信息过时的情况。客服人员忙碌接待时&#xff0c;往往来不及截图上报&#xff0c;就只能眼睁睁看着错误信息发给买家。这…...

从医学影像到自动驾驶:Grad-CAM如何成为AI模型‘合规’与‘可信’的敲门砖?

Grad-CAM&#xff1a;撬动AI可信革命的视觉解释引擎 当一位放射科医生面对AI系统标注的肺部CT影像时&#xff0c;他真正需要的不只是一个"疑似恶性肿瘤"的结论&#xff0c;而是想知道&#xff1a;这个判断究竟基于病灶的哪些特征&#xff1f;同样&#xff0c;当自动驾…...

知识图谱-Neo4j实战指南:从安装到应用开发

1. 为什么选择Neo4j构建知识图谱 第一次接触Neo4j时&#xff0c;我被它处理复杂关系的效率震惊了。传统关系型数据库在处理多表关联查询时性能急剧下降&#xff0c;而Neo4j查询6度人脉关系只需毫秒级响应。这就像在拥挤的十字路口&#xff0c;关系型数据库是红绿灯指挥的车辆&a…...

kohya_ss训练SDXL模型避坑指南:从数据集准备到超参数调优

SDXL模型高效训练实战&#xff1a;从kohya_ss环境配置到LoRA微调全流程解析 如果你正在尝试用kohya_ss训练SDXL模型却频繁遇到报错&#xff0c;或是训练效果总是不尽如人意&#xff0c;这篇文章将带你避开那些新手常踩的坑。不同于基础教程&#xff0c;我们聚焦于实际训练中的高…...

深度学习驱动的遥感影像变化检测:技术演进与前沿应用

1. 遥感影像变化检测的深度学习革命 十年前我第一次接触遥感影像分析时&#xff0c;传统方法需要手工设计特征提取算法&#xff0c;光是处理一幅卫星图像就要花上大半天。现在用深度学习模型&#xff0c;一杯咖啡还没喝完就能完成整个区域的变化检测。这种技术飞跃的核心在于**…...