use strings to call functions

Gerard Flanagan grflanagan at gmail.com
Mon Feb 8 16:00:27 CET 2010


Klaus Neuner wrote:
> Hello,
> 
> I am writing a program that analyzes files of different formats. I
> would like to use a function for each format. Obviously, functions can
> be mapped to file formats. E.g. like this:
> 
> if file.endswith('xyz'):
>     xyz(file)
> elif file.endswith('abc'):
>     abc(file)
> 
> ...
> 
> Yet, I would prefer to do something of the following kind:
> 
> func = file[-3:]
> apply_func(func, file)
> 

As mentioned, a dictionary dispatch will do what you want, but you can 
also use the self-registering technique outlined here:

http://effbot.org/zone/metaclass-plugins.htm [Fredrik Lundh]

(For Plugin, read Handler in this case.)

One idea might be to have Handler classes such as:

class TextHandler(HandlerType):
     extensions = ['', 'txt', 'rst']

     def run(self, *args, **kw):
         .... do stuff


then the __init__ of HandlerType's metaclass:

         def __init__(cls, name, bases, attrs):
             for ext in attrs.get('extensions', []):
                 registry[ext] = cls

then use like:

  registry['txt']().run()

If you don't need state, you could perhaps make 'run' a staticmethod and 
store it rather than the class,

eg. registry[ext] = cls.run

and then just:

  registry['txt']()

hth

G.F

------------------------------------------------------------------------

registry = {}

class HandlerType(object):
     class __metaclass__(type):
         def __init__(cls, name, bases, attrs):
             for ext in attrs.get('extensions', []):
                 registry[ext] = cls

class TextHandler(HandlerType):
     extensions = ['', 'txt']

print registry




More information about the Python-list mailing list