简体   繁体   中英

Threading, inheritance

My code is composed of a queue thread class (called MyThread ), a class inheriting MyThread (Device) and many class inheriting Device (such as A , B , ...)

Device instantiate a FSM (state machine). So each Device ( A , B ,..) have the same FSM table.

Now I am trying to implement callbacks of the FSM for/in each device A , B , ...

Here is a sketch of my code:

1.Device module:

MAP = {
'initial' : 'none',
'events': [
    {'name': 'load', 'src': ['OFF', 'ON', 'none'], 'dst': 'LOADED'},
    ],
 'callbacks': {}
}
class Device(MyThread):
    def __init__(self, actor=None):
        MyThread.__init__(self, actor, self.__class__)
        self.MAP =MAP
        self.MAP['callbacks']['onload'] = lambda e: self.initialise()
        self.start()
    def startFSM(self):
        self.started = True
        self.fsm = Fysom(self.MAP)
        self.fsm.startup()

2.MyThread module:

class MyThread(threading.Thread):
    def __init__(self, actor, name):
        threading.Thread.__init__(self, name=name)
        self.actor = actor
    def run(self):
        pass

3.A:

class A(Device):    
    def __init__(self, actor=None):
        Device.__init__(self, actor)
        self.status = None
    def initialise(self):
        print "Here is A"

4.B:

class B(Device):    
    def __init__(self, actor=None):
        Device.__init__(self, actor)
        self.status = None
    def initialise(self):
        print "Here is B"

Current code simplified:

a = A()
b = B()
a.fsm.load()
b.fsm.load()

which will returns :

Here is B
Here is B

instead of :

Here is A
Here is B

or again: a.MAP['callbacks']['onload'] has same memory location as b.MAP['callbacks']['onload']

The point here is to focus on MAP attributes. The issue is that the function saved in self.MAP['callbacks']['onload'] override the last one. But basically they should have one MAP per Device (A, B, ...). And each device should save is own initialise method into his own MAP attribute.

The problem is here:

MAP = {
'initial' : 'none',
'events': [
    {'name': 'load', 'src': ['OFF', 'ON', 'none'], 'dst': 'LOADED'},
    ],
 'callbacks': {}
}
class Device(MyThread):
    def __init__(self, actor=None):
        MyThread.__init__(self, actor, self.__class__)
        self.MAP =MAP  # Problem!

You're making self.MAP a reference to MAP . So every instance of a class that inherits from Device ends up with a self.MAP property that's a reference to the exact same dict (the global MAP dict). What you really want is this, so that each instance gets its own dict:

from copy import deepcopy

MAP = {
'initial' : 'none',
'events': [
    {'name': 'load', 'src': ['OFF', 'ON', 'none'], 'dst': 'LOADED'},
    ],
 'callbacks': {}
}
class Device(MyThread):
    def __init__(self, actor=None):
        MyThread.__init__(self, actor, self.__class__)
        self.MAP = deepcopy(MAP)  # Make sure each MAP is unique.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM