Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在转换中,如何通过函数引用而不是函数名字符串定义回调函数_Python_Transitions - Fatal编程技术网

Python 在转换中,如何通过函数引用而不是函数名字符串定义回调函数

Python 在转换中,如何通过函数引用而不是函数名字符串定义回调函数,python,transitions,Python,Transitions,在转换中,回调的定义如下: State(name='solid', on_exit=['say_goodbye']) machine.add_transition('melt', 'solid', 'liquid', before='set_environment') 我想使用在另一个类中定义的回调函数 class MyClass(object): def func(self): print('nothing') class NarcolepticSuperhero(o

在转换中,回调的定义如下:

State(name='solid', on_exit=['say_goodbye'])
machine.add_transition('melt', 'solid', 'liquid', before='set_environment')
我想使用在另一个类中定义的回调函数

class MyClass(object):
    def func(self):
        print('nothing')
class NarcolepticSuperhero(object):

    # Define some states. Most of the time, narcoleptic superheroes are just like
    # everyone else. Except for...
    states = [State('asleep'), 'hanging out', 'hungry', 'sweaty', 'saving the world']

    def __init__(self, name):

        # No anonymous superheroes on my watch! Every narcoleptic superhero gets
        # a name. Any name at all. SleepyMan. SlumberGirl. You get the idea.
        self.name = name
        self.mc = MyClass()
        # Initialize the state machine
        self.machine = Machine(model=self, states=NarcolepticSuperhero.states, initial='asleep')
        self.machine.add_transition(trigger='wake_up', source='asleep', dest='hanging out', prepare=self.mc.func)

m = NarcolepticSuperhero('Superman')
m.wake_up()
并得到一个
TypeError:getattr():属性名必须是字符串

我的完整代码是这样的。我有几个任务,每个任务都有不同的方法。你知道一个英雄不能用同一个动作来打败不同的怪物

英雄也不能总是打败怪物。因此,基于
prepare
,我们将选择
retain
击败下一个

class Mission(object):
    def __init__(self, name):
        super().__init__()
        self.result = 0
        self._state = State(name=name, on_exit=self.on_exit, on_enter=self.on_enter)
        self.state = name
    def fire(self):
        print('checking state {}'.format(self.name))
        self.result = random.random()
    def on_enter(self):
        print('enter state {}'.format(self.name))
    def on_exit(self):
        print('checking state {}'.format(self.name))
    def condition1(self):
        return self.result > 0.6
    def condition2(self):
        return self.result > 0.3
    def condition3(self):
        return self.result > 0.1

class Robot(object):
    def __init__(self):
        super().__init__()
        self.a = Mission('a')
        self.b = Mission('b')
        self.c = Mission('c')
        self.states = [i._state for i in [self.a, self.b, self.c]]
        self.machine = Machine(model=self, states=self.states, initial=self.a.state, auto_transitions=False)
        self.machine.add_transition( trigger='go_out', source=self.a.state, dest=self.b.state , prepare = self.a.fire, conditions = [self.a.condition2], after = 'beat_next')
        self.machine.add_transition( trigger='go_back', source=self.a.state, dest=self.c.state , after = 'sleep')
        self.machine.add_transition( trigger='beat_next', source=self.b.state, dest=self.c.state , after = 'sleep')
        self.machine.add_transition( trigger='sleep', source=self.c.state, dest=self.a.state )

    def show_graph(self):
        self.graph.draw('state.png', prog='dot')
        display(Image('state.png'))

机器型号为
self
,因此我无法将其更改为
mc

一种可能的方法是将机器绑定到接口,而不是绑定到
NarcolepticsSuperHero
实例

class StateMachineInterface(object):
    superhero = None

    def __init__(self, superhero):
        self.superhero = superhero

    def start(self):
        """Initiate State Machine with all states and transitions"""
        machine = Machine(
            self,
            states=STATES,
            initial=INITIAL_STATE,
        )
        machine.add_transition(trigger='wake_up', source='asleep', dest='hanging out', prepare='wakeup_prepare_callback')

        return machine

    def wakeup_prepare_callback(self):
        return self.superhero.func()


# Usage:

m = NarcolepticSuperhero('Superman')
machine = StateMachineInterface(m)
machine.start()
machine.wake_up()

这一原则在

中提出,一种可能的方法是将您的机器绑定到接口,而不是
NarcolepticSuperhero
实例

class StateMachineInterface(object):
    superhero = None

    def __init__(self, superhero):
        self.superhero = superhero

    def start(self):
        """Initiate State Machine with all states and transitions"""
        machine = Machine(
            self,
            states=STATES,
            initial=INITIAL_STATE,
        )
        machine.add_transition(trigger='wake_up', source='asleep', dest='hanging out', prepare='wakeup_prepare_callback')

        return machine

    def wakeup_prepare_callback(self):
        return self.superhero.func()


# Usage:

m = NarcolepticSuperhero('Superman')
machine = StateMachineInterface(m)
machine.start()
machine.wake_up()

这一原则在

中有建议,您能提供一个完整的最小独立示例吗?我需要更多的信息来重现错误。另外:您使用的是哪个版本的转换?您是否试图在应该是
self.mc.func
时引用
mc.func
?@TalYarkoni,是的,这是我的错误。但这并不重要。我将尽快添加完整的测试代码。如果您进行了更改,您的示例似乎运行良好。@Talyrkoni,我使用的是来自pip的最新python3版本,但出现了一个错误。可以创建该类,但调用触发器时会引发错误。能否提供完整的独立示例?我需要更多的信息来重现错误。另外:您使用的是哪个版本的转换?您是否试图在应该是
self.mc.func
时引用
mc.func
?@TalYarkoni,是的,这是我的错误。但这并不重要。我将尽快添加完整的测试代码。如果您进行了更改,您的示例似乎运行良好。@Talyrkoni,我使用的是来自pip的最新python3版本,但出现了一个错误。可以创建该类,但调用触发器时会引发错误。