如何在 Pytransitions 中向现有状态对象添加标签?

在我分配给我们的项目中,我们使用pytransitions. 我们的状态被创建,配备了额外的属性,并首先作为对象一个一个地添加到列表中。然后这个State对象列表被传递给一个Machine对象。这是一个简单的例子:


from transitions import State


states = []

state_initial = State("initial", on_exit="some_callback")

text = "this is some text"

state.text = text

states.append(state)

这是一台机器的创建方式:


from transitions import Machine

from some_library import SomeClass

from my_module import user_transitions


class User:

    states = states

    initial_state = states[0]

    def __init__(self, some_param: str, another_param: SomeClass = default_param):

        self.machine = Machine(model=self,

                               states=User.states,

                               initial=User.initial_state,

                               transitions=user_transitions,

                               prepare_event="preparing_callback",

                               after_state_change="ending_callback")

我想做的是在状态对象创建时或之后向我的状态添加标签。我的意思是 中的标签transitions.extensions.states,所以我可以使用is_tag文档中的方法来获取它们。考虑到我的传统设置,类似state_initial.add_tags(["tag1", "tag2"])或 state_initial = State("initial", on_exit="some_callback", tags=["tag1", "tag2"]) 以任何其他方式。我该怎么做?


阿晨1998
浏览 103回答 1
1回答

一只萌萌小番薯

我的第一个建议是检查您是否可以通过使用专用TextState而不是仅分配附加属性来简化状态创建过程。这样,您可以使您的状态配置更易于理解。从 yaml 或 json 文件中读取机器配置也变得更加容易。from transitions import Machine, Statefrom transitions.extensions.states import Tags# option a) create a custom state class and use it by default# class TextState and CustomState could be combined of course# splitting CustomState into two classes decouples tags from the&nbsp;# original state creation codeclass TextState(State):&nbsp; &nbsp; def __init__(self, *args, **kwargs):&nbsp; &nbsp; &nbsp; &nbsp; self.text = kwargs.pop('text', '')&nbsp; &nbsp; &nbsp; &nbsp; super(TextState, self).__init__(*args, **kwargs)class CustomState(Tags, TextState):&nbsp; &nbsp; passclass CustomMachine(Machine):&nbsp; &nbsp; state_cls = CustomStatestates = []state_initial = CustomState("initial", text="this is some text")# we can pass tags for initializationstate_foo = dict(name="foo", text="bar!", tags=['success'])states.append(state_initial)states.append(state_foo)# [...] CustomMachine(model=self, states=User.states, initial=User.initial_state)但是您的问题是关于如何在创建状态后注入标签功能。可能是因为它需要重大的重构和深入挖掘来改变状态创建。添加state.tags = ['your', 'tags', 'here']很好,应该可以开箱即用地创建图形和标记。要开始state.is_<tag>工作,您可以更改其__class__属性:from transitions import Machine, Statefrom transitions.extensions.states import Tags# option b) patch __class__states = []state_initial = State("initial")state_initial.text = "this is some text"# we can pass tags for initializationstate_foo = State("foo")state_foo.text = "bar!"state_foo.tags = ['success']states.append(state_initial)states.append(state_foo)# patch all statesfor s in states:&nbsp; &nbsp; s.__class__ = Tags&nbsp; &nbsp; s.tags = []# add tag to state_foostates[1].tags.append('success')class User:&nbsp; &nbsp; states = states&nbsp; &nbsp; initial_state = states[0]&nbsp; &nbsp; def __init__(self):&nbsp; &nbsp; &nbsp; &nbsp; self.machine = Machine(model=self,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;states=User.states,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;initial=User.initial_state)user = User()user.to_foo()assert user.machine.get_state(user.state).is_success&nbsp; # works!assert not user.machine.get_state(user.state).is_superhero&nbsp; # bummer...但同样,根据我的经验,当您努力将机器配置与代码库的其余部分分开时,代码变得更加易于理解和重用。在代码中的某处修补状态并分配自定义参数可能会被下一个使用您的代码的人忽略,当状态在两个调试断点之间更改其类时肯定会令人惊讶。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python