- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我最近在 Python 中发现了一个轻量级、面向对象的状态机实现,称为转换 (https://github.com/pytransitions/transitions)。所以我正在尝试使用这些状态机,尤其是 HierarchicalGraphMachine。我想要的一个很好的功能是即使机器不移动(保持在相同状态)也可以存储访问状态的历史记录。
从我从示例中看到的情况来看,我们实际上无法以简单的方式做到这一点,因为 before_state_change
和 after_state_change
当机器的状态没有改变时没有被调用。所以在这种情况下我们不能扩展我们的历史。为了解决这个问题,我最终创建了一个 trigger_wrapper 函数:
def trigger_wrapper(self, trigger_name):
previous_state = self.state
result = None
try:
result = self.trigger(trigger_name)
except AttributeError as attribute_err:
print('Invalid trigger name: {}'.format(attribute_err))
except MachineError as machine_err:
print('Valid trigger name but not reachable: {}'.format(machine_err))
except Exception as err:
print('Cannot make transition with unknown error: {}'.format(err))
if result is False:
print('Trigger name reachable but condition(s) was not fulfilled')
....
current_state = self.state
# update history
.....
return result
然后,我们调用 trigger_wrapper 而不是 trigger:
before: machine.trigger('drink')
now: machine.trigger_wrapper('drink').
除此之外,通过设置
ignore_invalid_triggers = False
当初始化
Machine
并使用此
trigger_wrapper
函数,我们现在可以通过缓存异常知道机器无法移动的原因。
NestedState
的原因,它看起来很复杂。 .
finalize_event
的示例进行操作.一切顺利,但这个回调函数似乎不足以捕捉以下情况(我在代码中添加了 2 行额外的行):
... same setup as before
m.go()
m.internal()
m.reflexive()
m.condition()
m.go() # MachineError: "Can't trigger event go from state B!"
m.goo() # AttributeError: Do not know event named 'goo'.
>>> Expected: ['go', 'internal', 'reflexive', 'condition', 'go', 'goo']
>>> Expected: ['B', 'B', 'B', 'B', 'B', 'B']
换句话说,是否有另一个回调可以捕获由调用
invalid trigger
引起的异常? (示例中的 goo)或由
valid trigger but not reachable from the current state
引起(从状态 B 调用 go())?
最佳答案
正如您已经提到的,before_state_change
和 after_state_change
仅在发生转换时调用。这并不一定意味着状态更改,因为内部和自反转换也会触发这些回调:
from transitions import Machine
def test():
print("triggered")
m = Machine(states=['A', 'B'], transitions=[
['go', 'A', 'B'],
dict(trigger='internal', source='B', dest=None),
dict(trigger='reflexive', source='B', dest='='),
dict(trigger='condition', source='B', dest='A', conditions=lambda: False)
], after_state_change=test, initial='A')
m.go() # >>> triggered
m.internal() # >>> triggered
m.reflexive() # >>> triggered
m.condition() # no output
唯一不会触发
after_state_change
的事件这是
m.condition
因为转换被(未满足的)条件停止了。
after_state_change
是正确的地方。如果你想记录每个触发器/事件,你可以通过
finalize_event
来做到这一点。 :
'machine.finalize_event' - callbacks will be executed even if no transition took place or an exception has been raised
from transitions import Machine
event_log = []
state_log = []
def log_trigger(event_data):
event_log.append(event_data.event.name)
state_log.append(event_data.state)
m = Machine(states=['A', 'B'], transitions=[
['go', 'A', 'B'],
dict(trigger='internal', source='B', dest=None),
dict(trigger='reflexive', source='B', dest='='),
dict(trigger='condition', source='B', dest='A', conditions=lambda event_data: False)
], finalize_event=log_trigger, initial='A', send_event=True)
m.go()
m.internal()
m.reflexive()
m.condition()
print(event_log) # >>> ['go', 'internal', 'reflexive', 'condition']
print([state.name for state in state_log]) # >>> ['B', 'B', 'B', 'B']
回调传递给
finalize_event
将始终被调用,即使转换引发异常。通过设置
send_event=True
,所有回调都会收到
EvenData
包含事件、状态和转换信息以及出现问题时的错误对象的对象。这是我必须更改条件 lambda 表达式的方式。当
send_event=True
, 所有回调都需要能够处理
EventData
目的。
finalize_event
回调执行顺序可以在
this section中找到的文档。
finalize_event
仅对有效事件调用,这意味着该事件必须存在并且还必须在当前源状态上有效。如果应该处理所有事件,
Machine
需要扩展:
from transitions import Machine
log = []
class LogMachine(Machine):
def _get_trigger(self, model, trigger_name, *args, **kwargs):
res = super(LogMachine, self)._get_trigger(model, trigger_name, *args, **kwargs)
log.append((trigger_name, model.state))
return res
# ...
m = LogMachine(states=..., ignore_invalid_triggers=True)
assert m.trigger("go") # valid
assert not m.trigger("go") # invalid
assert not m.trigger("gooo") # invalid
print(log) # >>> [('go', 'B'), ('go', 'B'), ('gooo', 'B')]
每个型号都饰有
trigger
方法是
Machine._get_trigger
的一部分已分配
model
范围。
Model.trigger
可用于按名称触发事件,也可用于处理不存在的事件。您还需要通过
ignore_invalid_triggers=True
不养
MachineError
当事件无效时。
Machine
拆分日志记录可能更可行/更易于维护。并处理处理事件的日志记录,例如:
m = Machine(..., ignore_invalid_triggers=True)
# ...
def on_event(event_name):
logging.debug(f"Received event {event_name}") # or log_event.append(event_name)
m.trigger(event_name)
logging.debug(f"Machine state is {m.state}") # or log_state.append(m.state)
关于python - pytransitions/transitions : Is there any better way to store the history of visited state?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66424244/
我看过的每个示例和样式表都使用 a:visited 来设置链接样式。除了a:visited具有更高的特异性,:visited不应该是等价的和更简单的吗? 最佳答案 TL;DR:在撰写本文时,您是完全正
每当我激活 Woocommerce 时,Woocommerce 都会在 Wordpress 的管理栏中添加“访问商店”。这导致我在那里同时拥有“访问站点”和“访问商店”。 但是,我真的看不出这样做有什
我已经看到了两种方式的例子,特别是维基百科展示了一个例子,其中被访问的对象决定了访问顺序,我认为这是一种听起来很合理的方法。 我处于需要多个访问顺序的情况,因此让访问者决定访问顺序似乎是合理的。但是,
我的网站上有我的帖子模型。我的帖子模型有一个存储访问的列。当用户访问我的帖子时,应该递增 1。我完全知道该怎么做,但我的问题是当我在我的模型中将它递增 1 时,它递增 2!!!!! 我在我的 Cont
使用 C++14,我使用 boost::variant作为编译时多态的一种方式: using MyType = boost::variant; 这两个类都有一个方法 sayHello() .我想调用:
我在使用 a:visited(或另一个可能?)伪类时遇到问题。我想让链接在不同的元素中显示为不同的颜色(.link-box 中的黑色和#main-menu 中的红色,无论它们是否被访问过),他们首先这
nav ul li a:link, a:visited nav ul li a, visited 第一次,我使用方法1 为导航栏中的链接设置颜色。然后,当我在 section 中创建链接时,它采用存储
我已经在 IE F12 开发人员工具下运行了我的 Sharepoint 网站,控制台在我的 HTML 开头提到了以下错误:- SEC7115: :visited and :link styles ca
这篇文章的目的是什么? 在 bigquery 中,我需要使用 caveat 删除重复的行 对于访问者访问具有相同页面名称的页面,重复发生在同一次访问中。 分组不能解决问题 下面,我已尽我所能解释数据、
我有这个 php 代码: mysqli_query($link, 'UPDATE `blog_posts` SET `visit` = `visit` + 1 WHERE `id` = ' . $po
我有一张表,其中包含访问、已完成的应用程序和批准,每行作为邮政编码,我试图将表转换为每行是访问的表。由于我在 Excel 中,我试图在 VBA 中编写一个宏来执行此操作,但这给了我一些不准确的地方。这
我有一个列出信息的页面,您可以在其中单击链接以获取更多详细信息。这些链接中的大多数都是正常的(即没有类),但在某些链接上我设置了类“未发布”(用于未发布的更改),其中样式设置为 color: red
我有一个列出信息的页面,您可以在其中单击链接以获取更多详细信息。这些链接中的大多数都是正常的(即没有类),但在某些链接上我设置了类“未发布”(用于未发布的更改),其中样式设置为 color: red
我在一个数学网站上工作,它有一些练习,页面底部有解决方案。我想让解决方案在用户滚动时隐藏起来,并且需要单击该 block 才能显示答案。我只想使用 css 和 html 来实现这一点。这是我到目前为止
在我的浏览器中,Mac OS 上的 Chrome,文本装饰和背景颜色不适用于以下代码: http://jsfiddle.net/5CYHZ/10/ 为什么会这样? 最佳答案 Mozilla出于隐私原因
我无法在 Firefox 或 IE 中处理 a:visited 超链接 如果我设置 a:visited 的背景颜色,它会正常工作,但不透明度不会设置。 有什么想法吗? 这是我的CSS: a.photo
我正在尝试使用 std::visit 来检查 std::variant。 首先,我声明变体和变体的基(可调用)访问者类: #include #include #include using Ama
我有一个页面,我们在其中显示嵌入式画面仪表板,并且在同一页面上有一个下拉菜单,用户可以使用该下拉菜单加载不同的仪表板,单击我调用的下拉选项 Turbolinks.visit(url, {action:
我想更改页面上两个链接的访问颜色。我有办法做到这一点吗? 最佳答案 仅在您想要不同访问颜色的链接上放置一个类,例如: Different 在 CSS 中,然后以您想要的任何方式设置已访问过的链接类别的
不确定这是否可能,而不必经过几次传递,但我无论如何都会问(我的 XSL 有点生锈) 我有一个 XML 文档,其中包含如下节点:
我是一名优秀的程序员,十分优秀!