Using String Methods In Jump Tables

John Pinner funthyme at gmail.com
Tue Aug 24 15:49:08 CEST 2010


On Aug 20, 12:27 am, Tim Daneliuk <tun... at tundraware.com> wrote:
> Problem:
>
>   Given tuples in the form (key, string), use 'key' to determine
>   what string method to apply to the string:
>
>     key           operation
>     -----------------------
>
>      l            lower()
>      u            upper()
>      t            title()
>      ...
>
> Commentary:
>
>    Easy, right?  Well ... except that I would really, really like
>    to avoid cascading ifs or eval based solutions.  I'd like to implement
>    this as a jump table dictionary:
>
>      jt = { 'l' : lower_function reference,
>             'u' : upper_function reference,
>              ...
>           }
>
>    So I could then do this:
>
>      string = jt[key](string)
>
> But There's A Problem:
>
>    I tried to do this:
>
>      jt = {'l', "".lower,
>            'u', "".upper,
>            ...
>           }
>
>    You can get away with this because all string objects appear to point to common
>    method objects.  That is,: id("a".lower) == id("b".lower)
>
>    HOWEVER, you cannot then do this:
>
>      string = jt[key](string)
>
>    Why?  Because the methods of a string, while common to all strings
>    *do not accept an arg*.  They are implemented to "know" about the
>    string instance they "belong to" (that contains them).
>
> (Forgive me here, I am probably not using some of the OO arcana properly...)
>
> I realize that the string module has many of the same functions that
> are found as methods on strings.  But it doesn't have all of them -
> the .title() method is notably absent.  If this were not the case,
> I could happily do things like 'l' : string.lower  and my approach
> would work fine.  
>
> Even if I could use the string module, I'd still be curious though:
>
>    How do you get a reference to a method found in one object instance, but
>    actually apply it to another instance of the same class?  I'm guessing this may
>    involve fiddling with some of the internal __ variables, but I'm not
>    quite sure where to go next.
>
> As I said, I know I could do this as a set of cascading ifs or even as an
> eval, but I'm loathe to use such approaches. I like jump tables as a
> structural construct because they are easy to understand and maintain. I
> also realize that what I'm asking may be violating some deeply held notion
> of OO purity, but, well, now I'm just curious if there is a way to do this

I think the solution to what you are asking for is to use getattr(),
eg:

>>> ops={'u':'upper','l':'lower'}
>>> s='hello world'
>>> getattr( s, ops['u'] )()
'HELLO WORLD'
>>>

For info on getattr() see:

http://docs.python.org/library/functions.html#getattr
or
http://effbot.org/zone/python-getattr.htm

Best wishes,

John
--



More information about the Python-list mailing list