练习 30:有限状态机

每当你阅读一本关于解析的书,都有一个可怕的章节,关于有限状态机(FSM)。他们对“边”和“节点”进行了详细的分析,每个可能的“自动机”的组合被转换成其他自动机,坦率地说,它有点多了。FSM 有一个更简单的解释,使得它们实用并且可理解,而不会违背相同主题的纯理论版本。当然你不会向 ACM 提交论文,因为你不知道 FSM 背后的所有数学知识,但如果你只想在应用程序中使用它们,那么它们就足够简单了。

FSM 是组织事件一种方式,事件发生在一系列状态上。定义事件的另一种方法是“输入触发器”,类似于if语句中的布尔表达式,但通常不太复杂。事件可以是按钮点击,从流中接收字符,更改日期或时间,以及几乎任何用于声明事件的东西。状态就是你的 FSM 停止的任何“位置”,同时它等待更多的事件,并且你定义的每个状态都允许事件(输入)。事件往往是暂时的,而状态通常是固定的,而且二者都是可以存储的数据。最后,你可以将代码附加到事件或状态,甚至决定在进入状态时,状态中或退出状态时是否应运行代码。

FSM 只是一种方法,在执行中不同位置发生不同事件时,使用白名单列出可能运行的代码。在 FSM 中,当你收到意外事件时,你会发生故障,因为你必须明确说明每个状态允许哪些事件(或条件)。if语句也可以处理可能的分支,但它是一个可能性的黑名单。如果你忘记了else子句,那么你的if-elif条件没有覆盖的任何东西都会退回默认。

让我们将其拆解:

你拥有状态,这是 FSM 当前所在位置的存储指示器。状态可以是“开始”,“按下某键”,“中止”或类似的方式,描述执行的可能位置中的 FSM 的位置。每个状态都意味着正在等待某事发生,在决定下一步做什么之前。

你拥有事件,可以将 FSM 从一个状态移动到另一个状态。事件可以是“按下某键”,“套接字连接失败”,“文件保存”,并表示 FSM 接收到一些外部刺激,因此必须决定要做什么,以及下一个状态是什么。一个事件甚至可以回到同一个状态,这是你循环的方式。

根据发生的事件,FSM 从一个状态转换到另一个状态,并且仅仅由于为状态提供的确切事件(尽管其中一个事件可以定义为“任何事件”)。他们不会“意外”转移状态,你可以通过查看收到的事件和访问的状态,精确地跟踪他们从一个状态转移到另一个状态。这使得它们非常容易调试。

在状态转换之前,之后和期间,你可以在每个事件上运行代码。这意味着你可以在收到事件时运行一些代码,然后决定在该状态下基于该事件做什么,然后在离开该状态之前再次运行代码。这种执行代码的功能使得 FSM 非常强大。

有时候“没有”也是一个事件。这很好很强大,因为这意味着即使没有发生任何事情,你也可以将 FSM 转换到新的状态。然而,实际上,“没有”往往是隐含的事件“再来一次”或“醒来”。在其他情况下,这个状态的意思是,“不确定,也许下一个事件会告诉我是什么状态。”

FSM 的力量是能够明确地说明每个事件,事件只是正在接收的数据。这使得它们非常容易进行调试,测试和正确实现,因为你确切地知道每个状态的可能性,以及在每个状态中,对于每个事件可能发生的情况。在本练习中,你将要研究 FSM 库和使用它的 FSM 实现,来了解它们如何工作。

挑战练习

我创建了一个 FSM 模块,处理一些简单的事件来处理 Web 服务器的连接。这是一个虚构的 FSM,为你提供一个在 Python 中快速编写 FSM 的例子。它只是处理连接的基本框架,连接从套接字读取和写入,并且它缺少一些重要的东西,但这只是供你使用的一个很小的例子。

def START():

return LISTENING

def LISTENING(event):

if event == "connect":

return CONNECTED

elif event == "error":

return LISTENING

else:

return ERROR

def CONNECTED(event):

if event == "accept":

return ACCEPTED

elif event == "close":

return CLOSED

else:

return ERROR

def ACCEPTED(event):

if event == "close":

return CLOSED

elif event == "read":

return READING(event)

elif event == "write":

return WRITING(event)

else:

return ERROR

def READING(event):

if event == "read":

return READING

elif event == "write":

return WRITING(event)

elif event == "close":

return CLOSED

else:

return ERROR

def WRITING(event):

if event == "read":

return READING(event)

elif event == "write":

return WRITING

elif event == "close":

return CLOSED

else:

return ERROR

def CLOSED(event):

return LISTENING(event)

def ERROR(event):

return ERROR

也有一个小测试,向你展示如何运行这个 FSM:

import fsm

def test_basic_connection():

state = fsm.START()

script = ["connect", "accept", "read", "read", "write", "close", "connect"]

for event in script:

print(event, ">>>", state)

state = state(event)

你在本练习中的挑战是,将此示例模块变成一个更强大和通用的 FSM Python 类。你应该使用它作为一系列线索,来了解如何处理进入的事件,状态如何作为 Python 函数,以及如何进行隐式的转换。看看我有时候为下一个状态返回函数,但其​​他时候我会返回一个状态函数的调用?试着弄清楚为什么我会这样做,因为它在 FSM 中非常重要。

为了完成这个挑战,你需要学习 Python inspect模块,看看你可以用 Python 对象和类来做什么。有一些特殊的变量,如__dict__以及inspect中的函数,可帮助你窥探类或对象并查找函数。

你也可以决定要反转此设计。你可以将事件作为子类中的函数,并在事件函数内检查当前的self.state,来确定接下来要执行的操作。这完全都取决于你正在处理什么,你是否拥有更多的事件还是状态,当时什么有意义。

最后,你可以使用一个设计,其中有一个FSMRunner类,它只知道如何运行这样设计的模块。这比一个知道如何运行自身实例的单一类有一些优点,但也有一些问题。例如,FSMRunner如何跟踪当前状态?它放在模块中还是在FSMRunner的实例中?

研究性学习

使你的测试更加泛用,并为你熟悉的完全不同的领域做一个FSM。

添加一个功能,启动在你的实现中运行的事件的日志。使用 FSM 处理事件的最大优点之一是,可以存储和记录 FSM 收到的所有事件和状态。这可以让你调试,为什么它达到你不需要的状态。

深入学习

你应该仔细研究 FSM 背后的数学。我这里的小例子不是完全形式化的概念版本,以便你能理解它。

python描述器 有限状态机_笨办法学 Python · 续 练习 30:有限状态机相关推荐

  1. 笨办法学python第五版_笨办法学python PDF下载|笨办法学python第五版 电子版附目录_最火软件站...

    笨办法学Python第五版PDF电子版是专门为初学Python的朋友准备的一款电子图书资料,可以帮助你更好的学习Python编程知识,该电子书每章节都附带了常见问题回答以及练习题目,能够帮助学习者快速 ...

  2. python考试代码复制_笨办法学Python 习题 26: 恭喜你,现在可以考试了! 错误代码下载链接...

    你已经差不多完成这本书的前半部分了,不过后半部分才是更有趣的.你将学到逻辑,并通过条件判断实现有用的功能. 在你继续学习之前,你有一道试题要做.这道试题很难,因为它需要你修正别人写的代码.当你成为程序 ...

  3. 笨办法学python第五版_笨办法学Python(五)

    习题 5: 更多的变量和打印 我们现在要键入更多的变量并且把它们打印出来.这次我们将使用一个叫"格式化字符串(format string)"的东西. 每一次你使用 " 把 ...

  4. 笨方法学python第六版_笨办法学Python(六)

    习题 6: 字符串(string)和文本 虽然你已经在程序中写过字符串了,你还没学过它们的用处.在这章习题中我们将使用复杂的字符串来建立一系列的变量,从中你将学到它们的用途.首先我们解释一下字符串是什 ...

  5. 笨办法学python pdf 第三版_笨办法学python第三版

    笨办法学python第三版pdf电子书是一本Python学习参考书,是美国程序员Zed A.Shaw编著,通过简单通俗的方法,结合内部的集体,让程序员学懂python,适用于初级学习python编程的 ...

  6. 笨办法学python在线阅读_笨办法学python全集.pdf

    TableofContents 笨办法学Python 1.1 序言 1.2 前言 1.3 简介 1.4 练习0.安装和准备 1.5 练习1.第一个程序 1.6 练习2.注释和井号"#&quo ...

  7. 笨办法学python3进阶篇下载_笨办法学Python 3 进阶篇

    书名:"笨办法"学Python 3:进阶篇 定价:59.0 ISBN:9787115505392 作者: 泽德·A. 肖 版次:第1版 出版时间:2020-06 内容提要: 本书是 ...

  8. 笨方法学 python3进阶篇_笨办法学Python 3 进阶篇

    部分准备知识1 如果不喜欢作者的个人流程怎么办2 如果发现自己太糟糕怎么办2 习题0准备工作3 程序员用的编辑器3 Python3.63 工作终端4 pip和virtualenv的配置4 实验笔记4 ...

  9. 笨办法学python3进阶篇_笨办法学Python 3 进阶篇

    第 一部分 准备知识 1 如果不喜欢作者的个人流程怎么办 2 如果发现自己太糟糕怎么办 2 习题0 准备工作 3 程序员用的编辑器 3 Python 3.6 3 工作终端 4 pip和virtuale ...

最新文章

  1. JSP由浅入深(1)—— 熟悉JSP服务器
  2. 如何汉化DNN--中文语言包的使用
  3. 网络带宽由什么决定_你的二手奢侈品价格到底由什么决定,奢侈品回收标准是什么...
  4. hhkb mac设置_把 HHKB 放在 MacBook 上使用的解决方案
  5. android的Imageview的src和background
  6. Spring Boot + Thymeleaf + Activiti 快速开发平台项目,附源码!
  7. Python对zip、tgz、rar压缩包的解压与读取
  8. fc安卓模拟器_安卓电视卡丑慢!装上它们,像iOS一样省心易用
  9. Selenium自动化中无头浏览器的应用
  10. 怎么制定合理的开发计划
  11. 什么是PID?讲个故事,通俗易懂
  12. 如何看待培训机构出来的非科班程序员
  13. Git入门之日志和版本回退
  14. 对js原型对象的理解
  15. ros中的map_server package分析
  16. Matlab 入门01
  17. bigemap下载地图操作步骤(卫星地图、电子地图…)
  18. 的修报修系统是什么?的修报修系统好不好用?
  19. adb命令安装安卓apk包(首先解决adb不是内部命令或者不是外部命令)
  20. COM, COM+ 和 .NET 的区别

热门文章

  1. 暑期训练日志----2018.8.24
  2. 最优乘车(信息学奥赛一本通-T1377)
  3. 统计天数(洛谷-P1567)
  4. 信息学奥赛C++语言: 选夏令营旗手1
  5. 信息学奥赛C++语言:某年某月天数
  6. 数组中查找並返回数组_剑指 Offer 04. 二维数组中的查找
  7. 关于fi dd ler 手机抓包 网卡地址地址_136w、136nw、138pnw 通过手机设置无线连接
  8. torch.nn.Parameter()
  9. knime实现python编写脚本
  10. matlab算法应用论文(带代码)_左手论文 右手代码 深入理解网红算法XGBoost