Context:I have to create an interface between devices and a client.My package is composed of:Device.pyError.pyDeviceA.py (for example)DeviceB.py...Basically each DeviceA, DeviceB, ... inherit Device class. Device is composed of one FSM (state machine: module Fysom) and does several thing about communication, parsing, ... The purpose is to have one common FSM (same rules) for all devices but each device follow his own FSM. That's why there is one thread per device (Device inherit a Threading module).A code simplified:# One common state ruleTableFSM = {'initial' : 'none','events': [    {'name': 'do_start', 'src': ['OFF', 'none'], 'dst': 'LOADED'},    {'name': 'do_stop', 'src': ['LOADED'], 'dst': 'OFF'},    # same for resume, pause, ...]class Device(MyThread):    def __init__(self):        # FSM is instantiate here so ONE FSM per device with same rule        self.fsm = Fysom(TableFSM)        self.mode = operation #or simulation    def start(self):        self.fsm.do_start()        # Real common Device parsing stuff    def stop(self):        self.fsm.do_stop()        # Real common Device parsing stuff    def pause(self):        self.fsm.do_pause()        # Real common Device parsing stuff    def resume(self):        self.fsm.do_resume()        # Real common Device parsing stuffclass DeviceA(Device):    def __init__(self):        Device.__init__(self)    def start(self):        #Specific Real Device stuff        super(DeviceA, self).start()    def stop(self):                    #Specific Real Device stuff        super(DeviceA, self).start()    #def ...class DeviceB(Device):    def __init__(self):        Device.__init__(self)    def start(self):        #Specific Real Device stuff        super(DeviceB, self).start()    def stop(self):                    #Specific Real Device stuff        super(DeviceB, self).start()    #def ...Here methods called will be DeviceA().start() or DeviceB().stop() (bad represention) for example. Issue:I have to implement for each device an operation and simulation modeFor example  I could add in each method of each device class the following statement:if self.mode == operation:    #some stuffelif self.mode == simulated:    #almost nothingI want to write it as generic as possible.From a previous post I could derivate SimuDevice from Device with the same methods. Basically SimuDevice will only trigger the FSM :class DeviceSimu(Device):    def __init__(self):        Device.__init__(self)    def start(self):        self.fsm.do_start()    def stop(self):        self.fsm.do_stop()    def pause(self):        self.fsm.do_pause()    def resume(self):        self.fsm.do_resume()Question:My issue is about instanciation and object. I want to be able to switch between operation and simulation mode without deleting and reinstantiate an object.I can't understand how DeviceA could access to DeviceSimu method? Is it a good way (conceptually) to do simulation and operation mode? Maybe I have to change the link between class.Any other advice ?
Implement operation and simulation mode in an interface
python;simulation
You could simply have if-statements in each method of your class. This would probably result in (slightly) lesser lines of code than my suggestions. However, I think that solution has a lot of repeated code and is quite static. What if you wanted a device that simply simulates? Or one that simply operates?My suggestion is to abstract the classes a bit more and have seperate classes for each mode. Then have a final DualModeDevice class that inherits from both of them: class OperationDevice(Device):    def __init__(self):        super(OperationDevice, self).__init__()    def operation_start(self):        # Do operation specific code        self.start()    def operation_stop(self):        # Do operation specific code        self.stop()    def operation_pause(self):        # Do operation specific code        self.pause()    def operation_resume(self):        # Do operation specific code        self.resume()class SimulationDevice(Device):    def __init__(self):        super(SimulationDevice, self).__init__()    def simulation_start(self):        # Do simulation specific code        self.start()    def simulation_stop(self):        # Do simulation specific code        self.stop()    def simulation_pause(self):        # Do simulation specific code        self.pause()    def simulation_resume(self):        # Do simulation specific code        self.resume()class DualModeDevice(OperationDevice, SimulationDevice):    def __init__(self, mode='simulation'):        super(DualModeDevice, self).__init__()        self._mode = mode        # To be continued Each function in SimulationDevice and OperationDevice needs to be named differently because of how Python interprets and resolves inheritence. If there is a identically named function from multiple inheritances, it will use the first available reference from the MRO (method resolution order).Now with that being said, you could implement dual mode in two ways:Function mappingOne way is to simply have a dict that holds a mapping from mode to function:class DualModeDevice(OperationDevice, SimulationDevice):    def __init__(self, mode='simulation'):        super(DualModeDevice, self).__init__()        self._mode = mode        self._start_map = {            'simulation': self.simulation_start,            'operation': self.operation_start        }        # Repeat the above line for `stop`, `pause`, and `resume`.        # Or you could combine them into a single `dict`.    def stop(self):        self._start_map[self._mode]()    def stop(self):        self._stop_map[self._mode]()getattrIf you felt like being sneaky, you could use the getattr function (assuming consistent function names):class DualModeDevice(OperationDevice, SimulationDevice):    def __init__(self, mode='simulation'):        self._mode = mode    def run_command(self, command, mode=self.mode):        getattr(self, '{}_{}'.format(mode, command))()Since functions boil down to callable properties in classes, we can simply use getattr to get the correct function, then call it.