EventHandlers in python, anything like C#? Listening for serial messages

Viewed 417

Is it possible to have EventHandlers in Python like C#.

In C# I have an Event Handler for receiving data over a serial port, this stops the need for listening in a loop.

Like this:

private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    InputData = ComPort.ReadExisting();
    if (InputData != String.Empty)
    {
        BeginInvoke(new SetTextCallback(SetText), new object[] { InputData });

        if (InputData == "0")
        {
            WriteToLog("COM IN = 0 GetFileNames");
            GetFileNames();
        }
        if (InputData == "1")
        {
            WriteToLog("COM IN = 1 GetFileCount");
            GetFileCount();
        }
        if (InputData == "2")
        {
            WriteToLog("COM IN = 2 GetFolderSize");
            GetFolderSize();
        }
        if (InputData == "3")
        {
            WriteToLog("COM IN = 3 Restart PC");
            RestartPC();
        }
    }
}

Is there any analogous way of doing this in python? as currently I am listening like this and it seems wasteful as it's just sitting there ticking away.

import time
import serial


ser = serial.Serial(

    port='/dev/ttyUSB0',
    baudrate = 9600,
    parity=serial.PARITY_NONE,
    stopbits=serial.STOPBITS_ONE,
    bytesize=serial.EIGHTBITS,
    timeout=1
)
counter=0


while 1:
    x=ser.readline()
    print x
1 Answers
import can

class Event:
    def __init__(self):
          self.handlers = set()
    def handle(self, handler):
        self.handlers.add(handler)
        return self

    def unhandle(self, handler):
        try:
            self.handlers.remove(handler)
        except:
            raise ValueError("no handler...")
        return self

    def fire(self, *args, **kargs):
        for handler in self.handlers:
            handler(*args, **kargs)

    def getHandlerCount(self):
        return len(self.handlers)

    __iadd__ = handle
    __isub__ = unhandle
    __call__ = fire
    __len__  = getHandlerCount


class BufferedReader(Listener):
    def __init__(self):
        self.buffer = queue.Queue(0)

    def on_message_received(self, msg):
        self.buffer.put(msg)

    def get_message(self, timeout=0.5):
        try:
            return self.buffer.get(block=True, timeout=timeout)
        except queue.Empty:
            return None

class MockPortWatcher(BufferedListener):
    def __init__(self):
        self.bus = can.interface.Bus('Event', bustype='virtual')
        self.portChanged = Event()
    def watchPort(self):
        source_path = "/dev/ttyS1"           
        msg = self.get_message()
        self.portChanged(msg)

    def get_message(self):
        msg = self.bus.recv()
        return msg

    def log_port_change(msg):
        print "%r we got message to handle:" % (msg)

since the question is to follow c# lang event syntax, we got much the same with python:

watcher = MockPortWatcher()
watcher.portChanged += log_port_change
watcher.watchPort()
Related