如何为“转换”状态机定义触发器的枚举?

2024-04-15

作为不相关的后续这个答案 https://stackoverflow.com/a/68269299/913098,它使用以下工作代码:

from transitions import Machine
from transitions import EventData
from typing import Callable
from enum import Enum, auto


class Observer:

    def state_changed(self, event_data: EventData):
        print(f"state is now '{event_data.state.name}'")


class State(Enum):
    SOLID = auto()
    LIQUID = auto()
    GAS = auto()


class SubscribableMachine(Machine):

    transitions = [
        {'trigger': 'heat', 'source': State.SOLID, 'dest': State.LIQUID},
        {'trigger': 'heat', 'source': State.LIQUID, 'dest': State.GAS},
        {'trigger': 'cool', 'source': State.GAS, 'dest': State.LIQUID},
        {'trigger': 'cool', 'source': State.LIQUID, 'dest': State.SOLID}
    ]

    def __init__(self):
        super().__init__(states=State, transitions=self.transitions,
                         initial=State.SOLID, send_event=True)

    def subscribe(self, func: Callable, state: State):
        self.get_state(state).on_enter.append(func)

    def unsubscribe(self, func: Callable, state: State):
        self.get_state(state).on_enter.remove(func)


machine = SubscribableMachine()
observer = Observer()
machine.subscribe(observer.state_changed, State.LIQUID)
machine.heat()  # >>> state is now 'LIQUID'
machine.heat()
assert machine.state == State.GAS
machine.unsubscribe(observer.state_changed, State.LIQUID)
machine.cool()  # no output
assert machine.state == State.LIQUID

我想要一个枚举Trigger以及,就像我有一个State.

唉,当我尝试时

class Trigger(Enum):
    heat = auto()
    cool = auto()

and

transitions = [
    {'trigger': Trigger.heat, 'source': State.SOLID, 'dest': State.LIQUID},
    {'trigger': Trigger.heat, 'source': State.LIQUID, 'dest': State.GAS},
    {'trigger': Trigger.cool, 'source': State.GAS, 'dest': State.LIQUID},
    {'trigger': Trigger.cool, 'source': State.LIQUID, 'dest': State.SOLID}
]

def __init__(self):
    super().__init__(states=State, transitions=self.transitions,
                     initial=State.SOLID, send_event=True)

I get

Traceback (most recent call last):
  File "C:/code/EPMD/Kodex/Algorithms/src/python/epmd/ablation_points/queries/dfgfdsg.py", line 42, in <module>
    machine = SubscribableMachine()
  File "C:/code/EPMD/Kodex/Algorithms/src/python/epmd/ablation_points/queries/dfgfdsg.py", line 33, in __init__
    initial=State.SOLID, send_event=True)
  File "C:\Code\EPMD\Kodex\EPD_Prerequisite\python_3.7.6\Lib\site-packages\transitions\core.py", line 589, in __init__
    self.add_model(model)
  File "C:\Code\EPMD\Kodex\EPD_Prerequisite\python_3.7.6\Lib\site-packages\transitions\core.py", line 607, in add_model
    self._add_trigger_to_model(trigger, mod)
  File "C:\Code\EPMD\Kodex\EPD_Prerequisite\python_3.7.6\Lib\site-packages\transitions\core.py", line 813, in _add_trigger_to_model
    self._checked_assignment(model, trigger, partial(self.events[trigger].trigger, model))
  File "C:\Code\EPMD\Kodex\EPD_Prerequisite\python_3.7.6\Lib\site-packages\transitions\core.py", line 807, in _checked_assignment
    if hasattr(model, name):
TypeError: hasattr(): attribute name must be string

我可以通过使用来解决它Enum's .name:

    transitions = [
        {'trigger': Trigger.heat.name, 'source': State.SOLID, 'dest': State.LIQUID},
        {'trigger': Trigger.heat.name, 'source': State.LIQUID, 'dest': State.GAS},
        {'trigger': Trigger.cool.name, 'source': State.GAS, 'dest': State.LIQUID},
        {'trigger': Trigger.cool.name, 'source': State.LIQUID, 'dest': State.SOLID}
    ]

但两者之间的不对称性State and Trigger打扰我。
难道我做错了什么?为什么枚举适用于State但不是Trigger?


As vish https://stackoverflow.com/a/68290769/1617563已经指出,没有办法直接使用枚举作为触发器。转换将触发器名称作为方法绑定到模型,因此要求触发器是字符串。然而,Machine所有子类在编写时都考虑到了继承。如果你想使用枚举而不是类和类属性,你可以派生一个合适的EnumTransitionMachine并得到统一的接口:

from transitions import Machine
from enum import Enum, auto


class State(Enum):
    A = auto()
    B = auto()
    C = auto()


class Transitions(Enum):
    GO = auto()
    PROCEED = auto()


class EnumTransitionMachine(Machine):

    def add_transition(self, trigger, *args, **kwargs):
        super().add_transition(trigger.name.lower() if hasattr(trigger, 'name') else trigger, *args, **kwargs)


transitions = [[Transitions.GO, State.A, State.B], [Transitions.PROCEED, State.B, State.C]]
m = EnumTransitionMachine(states=State, transitions=transitions, initial=State.A)
m.go()
assert m.state == State.B
m.proceed()
assert m.is_C()

仅供参考:也可以使用Enums带有字符串值:

class State(Enum):
    A = "A"
    B = "B"
    C = "C"


class Transitions(Enum):
    GO = "GO"
    PROCEED = "PROCEED"

# you could use the enum's value then instead:
    def add_transition(self, trigger, *args, **kwargs):
        super().add_transition(trigger.value.lower() if hasattr(trigger, 'value') else trigger, *args, **kwargs)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何为“转换”状态机定义触发器的枚举? 的相关文章

  • Python CSV Writer 在文件末尾留下一个空行

    以下代码在 txt 文件末尾留下一个空白行 我怎样才能不让 writerows 不终止最后一行 with open fname wb as myFile Start the CSV Writer wr csv writer myFile d
  • Pytorch - 推断线性层 in_features

    我正在构建一个玩具模型来获取一些图像并进行分类 我的模型看起来像 conv2d gt pool gt conv2d gt linear gt linear 我的问题是 当我们创建模型时 我们必须计算第一个线性层的大小in features基
  • 如何在 Python 2.4 CSV 阅读器中禁用引用?

    我正在编写一个 Python 实用程序 需要解析一个我无法控制的大型且定期更新的 CSV 文件 该实用程序必须在仅提供 Python 2 4 的服务器上运行 CSV 文件根本不引用字段值 但Python 2 4版本的csv库 http ww
  • TCP打孔问题

    我尝试使用 Python 3 中概述的原则为防火墙编写一个基本的 TCP 打孔器本文 http www bford info pub net p2pnat index html 不过 我无法连接任何东西 这是代码 usr bin pytho
  • 将数字转换为整数列表[重复]

    这个问题在这里已经有答案了 我该如何写magic下面的函数 gt gt gt num 123 gt gt gt lst magic num gt gt gt gt gt gt print lst type lst 1 2 3
  • 使用 Matplotlib 的范围绘制图像的 3D 轮廓

    正如我所介绍的here https stackoverflow com questions 18792624 fits image input to a range in plot python 在二维中 我想知道如何 缩放 要绘制到绘图中
  • self.__dict__.update(**kwargs) 的风格是好是坏?

    在 Python 中 假设我有一些类 Circle 它继承自 Shape Shape 需要 x 和 y 坐标 此外 Circle 需要半径 我希望能够通过执行类似的操作来初始化 Circle c Circle x 1 y 5 r 3 Cir
  • 如何使用appium自动化Android手机后退按钮

    我正在使用 Appium python 客户端库 对 Android 上的混合移动应用程序进行测试自动化 我无法找到任何方法来自动化或创建手势以使用 电话后退 按钮返回到应用程序的上一页 有没有可以使用的驱动函数 我尝试了 self dri
  • 完全定制的Python帮助用法

    我正在尝试使用 Python 创建完全自定义的 帮助 用法 我计划将其导入到许多我想要具有风格一致性的程序中 但遇到了一些麻烦 我不知道为什么我的描述忽略换行符 尝试过 和 我无法让 出现在 ARGS 行的 换行符之后 显然它们坐在自己的行
  • python - 将cookie添加到cookiejar

    如何在 python 中创建 cookie 并将其添加到 CookieJar 实例 我拥有 cookie 的所有信息 名称 值 域 路径等 但我不想通过 http 请求提取新的 cookie 我尝试了这个 但看起来 SimpleCookie
  • 为什么最简单的 requests_mock 示例在 pytest 中失败?

    我有一个特殊的问题requests mock 我想用它pytest测试我的 API 包装器库 我尝试过使用requests mock 文档中的第一个示例 http requests mock readthedocs io en latest
  • 如何打印和显示子进程 stdout 和 stderr 输出而不失真?

    也许有人可以帮助我解决这个问题 我在 SO 上看到了许多与此类似的问题 但没有一个问题同时处理标准输出和标准错误 也没有处理像我这样的情况 因此出现了这个新问题 我有一个 python 函数 它打开一个子进程 等待它完成 然后输出返回代码以
  • 收到“/:未找到事件。”使用 PyCharm 远程调试器时

    当我使用 PyCharm 通过 ssh 进行远程调试时tcsh shell 服务器 很多时候它停止工作 并显示 未找到事件 更具体地说 我在 pycharm 调试控制台中遇到以下内容 ssh username hostserver 22 p
  • Python 包安装:pip 与 yum,还是两者一起安装?

    我刚刚开始管理 Hadoop 集群 我们使用 Bright Cluster Manager 直至操作系统级别 CentOS 7 1 然后使用 Ambari 以及适用于 Hadoop 的 Hortonworks HDP 2 3 我不断收到安装
  • 如何从 IDLE 命令行运行 Python 脚本?

    在 bash shell 中 我可以使用 bash 或 source 手动调用脚本 我可以在 Python IDLE 的交互式 shell 中做类似的事情吗 我知道我可以转到文件 gt gt 打开模块 然后在单独的窗口中运行它 但这很麻烦
  • 对 Python 列表元素进行分组

    我有一个 python 列表 如下所示 my list 25 1 0 65 25 3 0 63 25 2 0 62 50 3 0 65 50 2 0 63 50 1 0 62 我想根据以下规则对它们进行排序 1 gt 0 65 0 62 l
  • Python 对列表中的值求和(如果它存在于另一个列表中)

    我有一个列表和一组 a list 1 2 2 1 1 1 b list 1 2 我正在寻找对应 b list 中的项目并将它们从 a list 中的值相加 以便输出为 1 3 2 1 我尝试过的 sum 0 for i in a list
  • python 相当于 sed

    有没有一种方法 无需双循环即可完成以下 sed 命令的操作 Input Time Banana spinach turkey sed i Banana s Toothpaste file Output Time BananaToothpas
  • Python Pandas:向类 pandas.core.series.Series 添加方法

    我想在 Python 中处理时间序列 因此 Pandas 的 Series 类非常完美 并且有很多有用的方法 现在我想添加一些我需要但未实现的方法 例如 假设我有兴趣添加一个方法 该方法将两次一值附加到时间序列中 让我们调用该方法appen
  • 如何继承并重写 django 模型类来创建 listOfStringsField?

    我想为 django 模型创建一个新类型的字段 它基本上是一个 ListOfStrings 因此 在您的模型代码中 您将具有以下内容 模型 py from django db import models class ListOfString

随机推荐

  • 在VB6中使用Sax解析编辑和编写XML

    因此 我尝试使用 VB6 中的 SAX 解析 对于古老的 COM 组件 来编辑 xml 输出是 xml 我更喜欢使用 DOM 解析 但 xml 的大小 可能超过 20MB 迫使我使用 SAX 我对 VB6 比较陌生 并且没有 SAX 解析经
  • 在这种情况下,数组索引中的字符表示如何工作?

    我是 C 初学者 我有这样的代码 include
  • 使用适用于 Android 的新 Facebook SDK 将内容添加到 Facebook feed 对话框

    我知道this https stackoverflow com questions 4450517 adding content to facebook feed dialog from facebook sdk for android线程
  • EntityFramework 是否可用于 Windows 8 应用商店应用程序?

    EntityFramework 是否可用于 Windows 8 应用商店应用程序 我正在使用适用于 Windows 8 的 Visual Studio 2012 Express 我开始怀疑 因为我无法让它发挥作用 我从 NuGet 安装了实
  • Delphi:使组件对实时绑定可见

    我一直在尝试制作一个具有对视觉绑定表单可见的字符串属性的测试对象 该组件已使用适当的属性进行注册 使用 XE8 和 Firemonkey 我可以通过使用隐藏显示元素选择它来使其显示在可视绑定器上 但是我无法让它将 Foo 字符串绑定到 TE
  • 如何更改 Kendo 警报标题?

    我正在使用 Kendo 警报并想更改其标题 默认标题是 url 名称 请参阅下面的链接 图片 我想使用自己的标题 如何更改 图像剑道警报 https i stack imgur com AscDa png 剑道警报 kendo alert
  • Graphviz 允许边缘节点重叠

    我想在项目中使用 graphviz 但无法获得我想要的行为 我有一个可以用 graphviz 绘制的图表 但我也有同一个图表的一个版本 它有一些额外的边 我希望绘制第二个图时 节 点与第一个图的位置相同 边缘也位于相同的位置 但绘制新的边缘
  • Silverlight 3:没有变化,但现在我收到“找不到页面”

    有一个工作正常的页面 我所做的唯一更改是向页面添加一个数据网格 其中还添加了 xmlns 突然间我得到了 找不到页面 检查了 UriMappings 尝试了默认导航链接 没有喜悦 Ideas 更新 答案是我有一个没有初始化集合的模拟类 请参
  • 何时使用filter_input()

    这个问题最初是在评论中提出的here https stackoverflow com questions 768442 php filter input comment 580014 Is 过滤器输入 http www php net ma
  • 在 VSCode 中每次保存时运行 rsync

    我的本地系统上有一个存储库 并正在远程服务器上测试我的更改 我正在使用 VSCode 进行开发 我希望每次保存时 rsync 都应在后台运行 并将当前本地文件中的更改与远程同步 我如何使用 VSCode 实现这一目标 我在用保存并运行 ht
  • 什么时候适合响应 HTTP 412 错误?

    我不清楚什么时候应该或不应该返回 HTTP 412 先决条件失败 Web 服务错误 我正在考虑在验证数据时使用它 例如 如果客户端 POST 的 XML 数据并且该数据缺少必需的数据元素 则以 412 和错误描述进行响应 这是否符合 HTT
  • UIImage 到 base64 字符串编码

    如何转换UIimage到base64编码的字符串 我找不到任何详细的示例或代码 我想知道你为什么没有找到你的问题 因为这是一个非常古老的问题并且可以找到here https stackoverflow com questions 39246
  • 具有自定义 PropertyDescriptor 的 PropertyGrid

    我一直在努力让自定义属性描述符按照我想要的方式使用 PropertyGrid 工作 前提 我有一个名为 Animal 的类 其中包含以下属性Age Type Location and Name 我有另一个名为 AnimalGroup 的类
  • 如何查询C++的GCC警告?

    GCC 允许使用以下语法查询特定于 C 语言的可用警告标志 g Q help warning c 向调用中添加警告标志会将它们包含在结果中 g Wall Q help warning c 然而 似乎调用是从 C 的角度完成的 我不知道如何从
  • 我无法导入textblob包

    我使用命令安装了textblobpip install 但现在我尝试导入它 但出现以下错误 ModuleNotFoundError 没有名为 textblob 的模块 我在Windows 10系统中使用Spyder from textblo
  • Draft.js (react-draft-wysiwyg):从编辑器组件外部进行文本更新不起作用

    我正在尝试将文本从调用组件更新到编辑器组件中 我用props从调用者传递文本 但是当文本更改 内容编辑器中更新属性 时 编辑器组件中的文本不是 下面是调用组件的代码
  • 如何在运行时跳过整个 Python“单元测试”模块?

    我想要我的Pythonunittestmodule 告诉测试运行者在某些情况下完全跳过它 例如无法导入模块或找到关键资源 我可以用 unittest skipIf 跳过单元测试 TestCase课程 但我如何跳过整个模块 对每个类应用跳过是
  • 在 wxPython 的面板之间拖动按钮

    有谁知道一个示例 其中展示了如何在 wxPython 中将按钮从一个面板拖动到另一个面板 我在面板中创建了一个位图按钮 我希望能够将其拖到另一个面板并将我放在那里 我还没有找到任何使用按钮的示例 只有文本和文件 我正在使用最新版本的 Pyt
  • Pandas 使用“更大”的 DataFrames 附加性能 concat/append

    问题 我将数据存储在 csv 文件中 其中包含以下列 data id value 我有 15 个文件 每个文件包含大约 10 20mio 行 每个 csv 文件涵盖一个不同的时期 因此时间索引不重叠 但列是重叠的 新 ID 不时输入 旧 I
  • 如何为“转换”状态机定义触发器的枚举?

    作为不相关的后续这个答案 https stackoverflow com a 68269299 913098 它使用以下工作代码 from transitions import Machine from transitions import