Python一些可能用的到的函数系列125 FSM工具transitions

说明

在这里插入图片描述

首先FSM是一个很有用的工具,在程序设计中,某个对象会对应若干不同的状态,在这个状态下,同样的方法会有不一样的行为。

python有个transitions包可以做这个,过去一直不想用,主要是感觉有点鸡肋。

本质上,FSM是一个较小的图,很自然地应该属于图的内容。在图这块,我使用networkx和neo4j来进行存储和处理。所以,理论上是可以自己实现transitions的功能的。

但是(肯定有但是),理论上可行与实际上的实现还有差距,我不太确定哪里没想明白,所以就先无脑的先使用这个包,来实现一些常见的需求。

内容

1 包信息

这个项目的github项目在这里

安装过程比较简单
pip install transitions

核心的功能(价值)我认为是这么一张图(虽然画图的环境也不是很好装)

在这里插入图片描述

2 使用

安装上还是使用豆瓣的源!pip install transitions -i https://mirrors.aliyun.com/pypi/simple/

关于原理就不多深究了,以下就看几个简单的使用,然后和应用场景关联起来。

2.1 基本概念

引入Machine对象,然后对于任意一个新的自建对象进行封装,然后就可以使用了

from transitions import Machine
class Switch:
    pass
# 定义状态机的状态
states = ['off', 'on']
# 定义状态机的转换规则
transitions = [
    {'trigger': 'switch_on', 'source': 'off', 'dest': 'on'},
    {'trigger': 'switch_off', 'source': 'on', 'dest': 'off'},
    {'trigger': 'switch_on', 'source': 'on', 'dest': 'on'}
]

# 创建状态机
machine = Machine(model=Switch, states=states, transitions=transitions, initial='off')

# 使用示例
switch = Switch()
# 初始状态为关闭
print(switch.state)
off

# 打开开关
switch.switch_on()
print(switch.state) 
on

# 再次打开开关,但已经是开启状态,不产生状态变化
switch.switch_on()
print(switch.state) 
on

状态(states)就是图里的点,transitions就是若干条边,其中第一个参数是边的类型(switch_on,switch_off),Machine对象会把这个变为实例的方法。

Action: 一个点和一条边的类型决定了一个动作。例如从 on 这个节点出发,有switch_on,switch_off两条边可以走,选择任意一条边,必然会达到一个终点on(环回)或者off。

基于这个基本概念,看下面两个更接近实战的例子

2.2 根据状态进行不同处理

这个可能是我目前最需要的应用,定义好不同的状态,每个状态都要进行处理,只不过处理的内容和方法可以根据状态而变。

from transitions import Machine

class ComplexMachine:
    pass
    def processing(self):
        if self.state =='active':
            print('I am active')
        elif self.state =='broken':
            print('Broken, needs repair')
        else:
            print('else')

# 定义状态机的状态
states = ['idle', 'active', 'broken']
# 定义状态机的转换规则
transitions = [
    {'trigger': 'activate', 'source': 'idle', 'dest': 'active'},
    {'trigger': 'deactivate', 'source': 'active', 'dest': 'idle'},
    {'trigger': 'break_machine', 'source': ['idle', 'active'], 'dest': 'broken'},
    {'trigger': 'repair_machine', 'source': 'broken', 'dest': 'idle'}
]

idle, active 和 broken可以对应于我的BT2对象的init, running, stop,所以其实还挺容易匹配上的。

就本例而言,这对应于一个机器的一般状态。把这个当成一个容器的控制对象也挺合适的。

# 创建状态机
machine = Machine(model=ComplexMachine, states=states, transitions=transitions, initial='idle')
# 使用示例
complex_machine = ComplexMachine()
# 初始状态为idle
print(complex_machine.state)  # 输出: idle

# 激活机器
complex_machine.activate()
print(complex_machine.state)  # 输出: active

complex_machine.processing()
I am active

# 破坏机器
complex_machine.break_machine()
print(complex_machine.state)  # 输出: broken

complex_machine.processing()
Broken, needs repair

# 修复机器
complex_machine.repair_machine()
print(complex_machine.state)  # 输出: idle

# 试图在broken状态下激活机器,但状态不会发生变化
complex_machine.break_machine()
complex_machine.activate()
print(complex_machine.state)  # 输出: broken

MachineError: "Can't trigger event activate from state broken!"

2.3 在执行之前的处理

这部分有点小小的问题,但还是能用。这有点像flask的before_handler, 在请求之前执行的动作。问题是函数的传参比较奇怪,必须把实例作为参数传进去。

from transitions import Machine
class ComplexMachine:
    def __init__(self):
        self.activation_message = None

    def set_activation_message(self, *args, **kwargs):
        self.activation_message = kwargs.get('message', None)

    def print_activation_message(self):
        print(f"Activation Message: {self.activation_message}")
        
# 定义状态机的状态
states = ['idle', 'active', 'broken']

# 定义状态机的转换规则
transitions = [
    {'trigger': 'activate', 'source': 'idle', 'dest': 'active', 'before': 'set_activation_message'},
    {'trigger': 'deactivate', 'source': 'active', 'dest': 'idle'},
    {'trigger': 'break_machine', 'source': ['idle', 'active'], 'dest': 'broken'},
    {'trigger': 'repair_machine', 'source': 'broken', 'dest': 'idle'}
]

实例化

# 导入 transitions 模块
from transitions import Machine

# 创建状态机
machine = Machine(model=ComplexMachine, states=states, transitions=transitions, initial='idle')

# 创建 ComplexMachine 实例
complex_machine = ComplexMachine()

# 输出初始状态
print(f"Current State: {complex_machine.state}")

# 触发激活操作
complex_machine.activate(complex_machine,message="Machine is now active")

Current State: idle
True

# 输出激活后的状态和消息
print(f"Current State: {complex_machine.state}")
complex_machine.print_activation_message()

Current State: active
Activation Message: Machine is now active

3 总结

以上,已经可以使用transitions 用于一类简单的应用:进行非常小的图状态管理。从图的查询来说,是从某个点触发,某一个有向边指向的下一个节点。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于springboot+vue的个人博客系统

博主主页:猫头鹰源码 博主简介:Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战,欢迎高校老师\讲师\同行交流合作 ​主要内容:毕业设计(Javaweb项目|小程序|Pyt…

Vue自定义商品发布组件

文章目录 一、代码展示二、代码解读三、结果展示 一、代码展示 <template><div><a-popover trigger"hover" :getPopupContainer"triggerNode > {return triggerNode.parentNode || document.body;}"><template #content><d…

Redis面试总结

概述 1. Redis是什么&#xff1f;简述它的优缺点&#xff1f; Redis本质上是一个Key-Value类型的内存数据库&#xff0c;很像Memcached&#xff0c;整个数据库加载在内存当中操作&#xff0c;定期通过异步操作把数据库中的数据flush到硬盘上进行保存。 因为是纯内存操作&…

[Angular 基础] - routing 路由(下)

[Angular 基础] - routing 路由(下) 之前部分 Angular 笔记&#xff1a; [Angular 基础] - 自定义指令&#xff0c;深入学习 directive [Angular 基础] - service 服务 [Angular 基础] - routing 路由(上) 使用 route 书接上回&#xff0c;继续折腾 routing 按照最初的 wi…

ffmpeg使用命令实现音视频分离

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、简单介绍二、具体操作三、验证1.源文件2.视频文件3.音频文件 四、补充总结 前言 有时候由于特殊需要可能需要将一个视频&#xff08;带音频&#xff09;的…

洛谷:P3068 [USACO13JAN] Party Invitations S(枚举、前缀和)

这题我们数据范围太大&#xff0c;用二维肯定是不行的&#xff0c;我们可以采用一维线性存储。 如题意&#xff0c;我们可以将每组奶牛编号都存在一维数组里面&#xff0c;只需记录每组的头尾指针就可以了。 如题中样例我们就可以存储成1 3 3 4 1 2 3 4 5 6 7 4 3 2 1 然后第…

docker部署aria2-pro

前言 我平时有一些下载视频和一些资源文件的需求&#xff0c;有时候需要离线下载&#xff0c;也要速度比较快的方式 之前我是用家里的玩客云绝育之后不再写盘当下载机用的&#xff0c;但是限制很多 我发现了aria2 这个下载器非常适合我&#xff0c;而有个大佬又在原来的基础…

基于 Vue3打造前台+中台通用提效解决方案(上)

基于 Vue3打造前台+中台通用提效解决方案 1、项目架构 本项目使用vite + vue3来实现前中台解决方案 2、为什么使用vite ? 因为,之前的项目一直都是使用webpack作为构建工具;vite出来这么久了,也没有用过;所以想在当前项目下进行使用; 2.1、为什么vite比webpack块? …

android开发文档下载,你的技术真的到天花板了吗

Android 基础 1.Activity 1、 什么是 Activity&#xff1f; 2、 请描述一下 Activity 生命周期 …… 2.Service 3.Broadcast Receiver32 4.ContentProvider 5.ListView 6.Intent 7.Fragment 1.Fragment 跟 Activity 之间是如何传值的 2.描述一下 Fragment 的生命周期 3.Fragme…

Qt多弹窗实现包括QDialog、QWidget、QMainWindow

1.相关说明 独立Widget窗口、嵌入式Widget、嵌入式MainWindow窗口、独立MainWindow窗口等弹窗的实现 相关界面包含关系 2.相关界面 3.相关代码 mainwindow.cpp #include "mainwindow.h" #include "ui_mainwindow.h" #include "tformdoc.h" #incl…

容器云平台巡检实战:运维进阶技巧与策略

1 docker容器日常巡检 通过以下方式进行检查&#xff1a; 1.1 docker/podman ps查看容器状态 Docker/podman ps -a 查看容器状态STATUS&#xff1a; Exited(0)&#xff1a;表示容器正常退出 Exited(其他数字)&#xff1a;容器异常退出&#xff0c;需要通过log 查看原因 Up…

080|为什么阿里的价值观值得你关注?

在阿里巴巴20周年年会现场&#xff0c;万众瞩目之下&#xff0c;马云和张勇完成了阿里巴巴董事长职务的交接。 不过你也知道&#xff0c;这次接棒在一年前就已经公布了&#xff0c;在年会上只是一个仪式。在20周年年会过后&#xff0c;我找到了互联网圈的资深媒体人阳淼&#…

julia语言使用PyCall包调用Python代码及Python包

Julia语言虽然好&#xff0c;但是包管理方面和生态环境感觉还有一点小小的缺陷&#xff0c;但是Julia可以调用Python丰富的包&#xff0c;用起来很方便。 安装PyCall 在安装之前先确认下Julia和Python的版本&#xff0c;我使用的稳定版本的 Julia1.6.7&#xff0c;Python版本是…

电磁兼容(EMC):单、双面PCB板设计要点

目录 1 产品设计原则&#xff1a;性价比为第一要素 2 布局设计要点 3 布线设计要点 4 完整地平面不是最优方案 1 产品设计原则&#xff1a;性价比为第一要素 PCB在电磁兼容设计中通常是要求有完整的地和电源平面。但多层价格让对价格敏感的产品望而却步&#xff0c;只能采…

GPT本地化研究(JAVA版本)

1.我觉得gpt3 600多G个人是不可能部署得成功的,回想我自己个人不可能每一方面知识都知道,我只是知道最多的是我自己擅长的,百事通需要靠大公司才能解决,我们只是要关注这个gpt是哪个领域的, 我想做的是工业—>自动化gpt(貌似这个方向日本很专业了*_*) 它山之石可以攻玉 2.gp…

【设计模式 03】抽象工厂模式

一个具体的工厂&#xff0c;可以专门生产单一某一种东西&#xff0c;比如说只生产手机。但是一个品牌的手机有高端机、中端机之分&#xff0c;这些具体的属于某一档次的产品都需要单独建立一个工厂类&#xff0c;但是它们之间又彼此关联&#xff0c;因为都共同属于一个品牌。我…

视觉Transformers中的位置嵌入 - 研究与应用指南

视觉 Transformer 中位置嵌入背后的数学和代码简介。 自从 2017 年推出《Attention is All You Need》以来&#xff0c;Transformer 已成为自然语言处理 (NLP) 领域最先进的技术。 2021 年&#xff0c;An Image is Worth 16x16 Words 成功地将 Transformer 应用于计算机视觉任务…

【go语言开发】yaml文件配置和解析

本文主要介绍使用第三方库来对yaml文件配置和解析。首先安装yaml依赖库&#xff1b;然后yaml文件中配置各项值&#xff0c;并给出demo参考&#xff1b;最后解析yaml文件&#xff0c;由于yaml文件的配置在全局中可能需要&#xff0c;可定义全局变量Config&#xff0c;便于调用 文…

面试题HTML+CSS+网络+浏览器篇

文章目录 Css预处理sass less是什么&#xff1f;为什么使用他们怎么转换 less 为 css&#xff1f;重绘和回流是什么http 是什么&#xff1f;有什么特点HTTP 协议和 HTTPS 区别什么是 CSRF 攻击HTML5 新增的内容有哪些Css3 新增的特性flex VS grid清除浮动的方式有哪些&#xff…

SAR ADC学习笔记(3)

一、SAR ADC采样电路 1.采样网络的时域响应&#xff1a;采保信号 2.采样网络的KT/C噪声 3.采样抖动 采样开关的种类 1.单MOS管开关 2.传输门开关 3.栅极自举&#xff08;Bootstrap&#xff09;开关 结论&#xff1a;M4的衬底需要和B点短接&#xff0c;保证B点能够到达高压&…