Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Choose Python function to call based on a regex

Is it possible to put a function in a data structure, without first giving it a name with def?

# This is the behaviour I want. Prints "hi". def myprint(msg):     print msg f_list = [ myprint ] f_list[0]('hi') # The word "myprint" is never used again. Why litter the namespace with it? 

The body of a lambda function is severely limited, so I can't use them.

Edit: For reference, this is more like the real-life code where I encountered the problem.

def handle_message( msg ):     print msg def handle_warning( msg ):     global num_warnings, num_fatals     num_warnings += 1     if ( is_fatal( msg ) ):         num_fatals += 1 handlers = (     ( re.compile( '^<\w+> (.*)' ), handle_message ),     ( re.compile( '^\*{3} (.*)' ), handle_warning ), ) # There are really 10 or so handlers, of similar length. # The regexps are uncomfortably separated from the handler bodies, # and the code is unnecessarily long.  for line in open( "log" ):     for ( regex, handler ) in handlers:         m = regex.search( line )         if ( m ): handler( m.group(1) ) 
like image 255
Tim Avatar asked Jul 08 '11 20:07

Tim


People also ask

Is match a regex function in Python?

match() re. match() function of re in Python will search the regular expression pattern and return the first occurrence. The Python RegEx Match method checks for a match only at the beginning of the string.

Is there a module that allow the use of regular expression in Python?

The Python module re provides full support for Perl-like regular expressions in Python. The re module raises the exception re. error if an error occurs while compiling or using a regular expression.

What is regualr expression Python?

A RegEx, or Regular Expression, is a sequence of characters that forms a search pattern. RegEx can be used to check if a string contains the specified search pattern.


2 Answers

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 
like image 161
Gareth Rees Avatar answered Sep 28 '22 09:09

Gareth Rees


Nicer DRY way to solve your actual problem:

def message(msg):     print msg message.re = '^<\w+> (.*)'  def warning(msg):     global num_warnings, num_fatals     num_warnings += 1     if ( is_fatal( msg ) ):         num_fatals += 1 warning.re = '^\*{3} (.*)'  handlers = [(re.compile(x.re), x) for x in [         message,         warning,         foo,         bar,         baz,     ]] 
like image 22
Udi Avatar answered Sep 28 '22 09:09

Udi