2017-06-02 127 views
0

我在Python中编写了一个StateMachine类,所以它可以继承。 它的逻辑按预期工作,但我可以从State访问属性self.data,该属性存在于派生的StateMachine类中,名称为StateMachineTest。产生Python类继承,attributeError

以下错误:

 
Traceback (most recent call last): 
File "/home/nbout/work/python/state_machine/main.py", line 68, in 
    main() 
File "/home/nbout/work/python/state_machine/main.py", line 59, in main 
    test = StateMachineTest() 
File "/home/nbout/work/python/state_machine/main.py", line 47, in __init__ 
    StateMachine.__init__(self, Started()) 
File "/home/nbout/work/python/state_machine/state_machine.py", line 17, in _init__ 
    self.current_state.on_enter(self) 
File "/home/nbout/work/python/state_machine/main.py", line 16, in on_enter 
    print("Started: data:{}".format(sm_test.data)) 
Started: on_enter 
AttributeError: 'StateMachineTest' object has no attribute 'data' 
Started: on_exit 

state_machine.py

class State: 

    def on_enter(self, state_machine): 
     pass 

    def on_exit(self, state_machine): 
     pass 


class StateMachine: 

    def __init__(self, start_state): 
     self.current_state = start_state 

     self.current_state.on_enter(self) 

    def __del__(self): 
     self.current_state.on_exit(self) 

    def set_state(self, state): 

     self.current_state.on_exit(self) 
     self.current_state = state 
     self.current_state.on_enter(self) 

main.py

from state_machine import StateMachine 
from state_machine import State 


class StateTest(State): 
    def pause(self, state_machine_test): 
     pass 

    def start(self, state_machine_test): 
     pass 


class Started(StateTest): 
    def on_enter(self, sm_test): 
     print("Started: on_enter") 
     print("Started: data:{}".format(sm_test.data)) 

    def on_exit(self, sm_test): 
     print("Started: on_exit") 

    def pause(self, sm_test): 
     print("Started: pause") 
     sm_test.set_state(Paused()) 

    def start(self, sm_test): 
     print("Started: start") 


class Paused(StateTest): 
    def on_enter(self, sm_test): 
     print("Paused: on_enter") 

    def on_exit(self, sm_test): 
     print("Paused: on_exit") 

    def pause(self, sm_test): 
     print("Paused: pause") 

    def start(self, sm_test): 
     print("Paused: start") 
     sm_test.set_state(Started()) 


class StateMachineTest(StateMachine): 

    def __init__(self): 
     StateMachine.__init__(self, Started()) 
     self.data = 10 

    def pause(self): 
     self.current_state.pause(self) 

    def start(self): 
     self.current_state.start(self) 


def main(): 

    test = StateMachineTest() 

    test.start() 
    test.pause() 
    test.pause() 
    test.start() 


if __name__ == '__main__': 
    main() 

回答

0

你的问题在于StateMachine.__init__(self, Started())需要selfdata atttribute已设置的事实,但你只把它的下一行(self.data = 10)。切换这两条线并重试!

+0

这是解决方法,谢谢。我将尽快接受你的答案StackOverflow让我...... – nbout

0

哇,这个代码是真的不必要地复杂化。

的问题似乎是,你在你的StateMachineTest类的初始化__init__Started,使其on_enter运行已设置self.data之前。

您可以通过将self.data的任务移到super以上来解决此问题,但更好的办法是简化继承层次结构。

+0

谢谢,那是我的问题。我使用继承来强制执行'StateMachine'类的可重用性 – nbout