Choose Python function to call based on a regex
This is based on Udi's nice answer.
I think that the difficulty of creating anonymous functions is a bit of a red herring. What you really want to do is to keep related code together, and make the code neat. So I think decorators may work for you.
import re# List of pairs (regexp, handler)handlers = []def handler_for(regexp): """Declare a function as handler for a regular expression.""" def gethandler(f): handlers.append((re.compile(regexp), f)) return f return gethandler@handler_for(r'^<\w+> (.*)')def handle_message(msg): print msg@handler_for(r'^\*{3} (.*)')def handle_warning(msg): global num_warnings, num_fatals num_warnings += 1 if is_fatal(msg): num_fatals += 1
Nicer DRY way to solve your actual problem:
def message(msg): print msgmessage.re = '^<\w+> (.*)'def warning(msg): global num_warnings, num_fatals num_warnings += 1 if ( is_fatal( msg ) ): num_fatals += 1warning.re = '^\*{3} (.*)'handlers = [(re.compile(x.re), x) for x in [ message, warning, foo, bar, baz, ]]
Continuing Gareth's clean approach with a modular self contained solution:
import re# in util.pyclass GenericLogProcessor(object): def __init__(self): self.handlers = [] # List of pairs (regexp, handler) def register(self, regexp): """Declare a function as handler for a regular expression.""" def gethandler(f): self.handlers.append((re.compile(regexp), f)) return f return gethandler def process(self, file): """Process a file line by line and execute all handlers by registered regular expressions""" for line in file: for regex, handler in self.handlers: m = regex.search(line) if (m): handler(m.group(1)) # in log_processor.pylog_processor = GenericLogProcessor()@log_processor.register(r'^<\w+> (.*)')def handle_message(msg): print msg@log_processor.register(r'^\*{3} (.*)')def handle_warning(msg): global num_warnings, num_fatals num_warnings += 1 if is_fatal(msg): num_fatals += 1# in your codewith open("1.log") as f: log_processor.process(f)