为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

阿晨1998 2022-05-24 16:00:13
在我分配给我们的项目中,我们使用pytransitions. 我们的状态被创建,配备了额外的属性,并首先作为对象一个一个地添加到列表中。然后这个State对象列表被传递给一个Machine对象。这是一个简单的例子:from transitions import Statestates = []state_initial = State("initial", on_exit="some_callback")text = "this is some text"state.text = textstates.append(state)这是一台机器的创建方式:from transitions import Machinefrom some_library import SomeClassfrom my_module import user_transitionsclass 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"]) 以任何其他方式。我该怎么做?
查看完整描述

1 回答

?
一只萌萌小番薯

TA贡献1795条经验 获得超7个赞

我的第一个建议是检查您是否可以通过使用专用TextState而不是仅分配附加属性来简化状态创建过程。这样,您可以使您的状态配置更易于理解。从 yaml 或 json 文件中读取机器配置也变得更加容易。


from transitions import Machine, State

from 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 

# original state creation code

class TextState(State):


    def __init__(self, *args, **kwargs):

        self.text = kwargs.pop('text', '')

        super(TextState, self).__init__(*args, **kwargs)


class CustomState(Tags, TextState):

    pass



class CustomMachine(Machine):

    state_cls = CustomState



states = []

state_initial = CustomState("initial", text="this is some text")

# we can pass tags for initialization

state_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, State

from 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 initialization

state_foo = State("foo")

state_foo.text = "bar!"

state_foo.tags = ['success']

states.append(state_initial)

states.append(state_foo)


# patch all states

for s in states:

    s.__class__ = Tags

    s.tags = []


# add tag to state_foo

states[1].tags.append('success')


class User:


    states = states

    initial_state = states[0]


    def __init__(self):

        self.machine = Machine(model=self,

                               states=User.states,

                               initial=User.initial_state)


user = User()

user.to_foo()

assert user.machine.get_state(user.state).is_success  # works!

assert not user.machine.get_state(user.state).is_superhero  # bummer...

但同样,根据我的经验,当您努力将机器配置与代码库的其余部分分开时,代码变得更加易于理解和重用。在代码中的某处修补状态并分配自定义参数可能会被下一个使用您的代码的人忽略,当状态在两个调试断点之间更改其类时肯定会令人惊讶。


查看完整回答
反对 回复 2022-05-24
  • 1 回答
  • 0 关注
  • 102 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号