在我分配的项目中,我们使用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("初始", on_exit="some_callback", tag=["tag1", "tag2"])
或考虑到我的遗留设置以任何其他方式。我该怎么办?
最佳答案
我的第一个建议是检查是否可以使用专用 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)
但是您的问题是关于如何在创建状态之后注入(inject)标签功能。可能是因为它需要重大重构和深入挖掘来改变状态创建。添加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...
但是,根据我的经验,当您努力将机器配置与代码库的其余部分分开时,代码会变得更加易于理解和可重用。修补代码中某处的状态并分配自定义参数可能会被下一个使用您的代码的人忽略,并且当状态在两个调试断点之间更改其类时,这肯定会令人惊讶。
关于python - 如何在 Pytransitions 中向现有状态对象添加标签?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57868795/