Using String Methods In Jump Tables

Jon Clements joncle at googlemail.com
Mon Aug 23 22:08:25 CEST 2010


On 23 Aug, 16:57, Tim Daneliuk <tun... at tundraware.com> wrote:
> On 8/23/2010 10:35 AM, Jon Clements wrote:
>
>
>
> > On 20 Aug, 01:51, Tim Daneliuk <tun... at tundraware.com> wrote:
> >> On 8/19/2010 7:23 PM, Steven D'Aprano wrote:
>
> >>> On Thu, 19 Aug 2010 18:27:11 -0500, Tim Daneliuk wrote:
>
> >>>> Problem:
>
> >>>>   Given tuples in the form (key, string), use 'key' to determine what
> >>>>   string method to apply to the string:
>
> >>>>>> table = {'l': str.lower, 'u': str.upper}
> >>>>>> table['u']('hello world')
> >>> 'HELLO WORLD'
>
> >> Aha!  That's just what I was looking for.
>
> >>> [...]
> >>>> 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
>
> >>> This is Python, not some "pure" OO language. We have functional
> >>> programming constructs, procedural constructs, and probably other
> >>> programming models as well. Screw the deeply held notion of OO purity :)
>
> >> Yeah, I've never been much impressed with the OO purists.  One of
> >> the best speeches on the subject I ever saw was by David Korn (of
> >> ksh fame) who did a presentation at USENIX one year called "Objecting
> >> To Objects".  He documented an attempt to write a compiler using
> >> purely OO constructs and the many rings of hell that ensued.  
>
> >>> But seriously, Python's object model includes bound and unbound methods
> >>> precisely so you can do this sort of thing, and the above table-based
> >>> approach is very common and recommended as an alternative to case/switch
> >>> statements. It's a very common Pythonic idiom, so never fear that people
> >>> will stone you for using it.
>
> >> +1
>
> >>> The only thing that is a bit unusual is that you call it a jump table. In
> >>> my experience, "Jump Table" is used for low-level languages where the
> >>> table values are memory addresses.
>
> >> Yeah ... those old assembler memories never quite fade do they.
> >> I dunno what you might call this.  A Function Dispatch Table
> >> perhaps?
>
> >> Thanks to both you and Chris for setting me straight :)
>
> >> --
> >> ------------------------------------------------------------------------
> >> Tim Daneliuk
> >> tun... at tundraware.com
>
> > Another more generic option would be to use methodcaller from the
> > operator module.
>
> > Just my 2p,
>
> > Jon.
>
> Could you say a bit more about just why you prefer this approach?
> Clearly, it *is* more generic, but in looking it over, it seems that
> methodcaller is less readable and intuitive ... at least to my eyes ...

In addition to Terry's informative response...

Using methodcaller allows you to 'preserve' Python's duck-typing as
well as any over-ridden methods in subclasses. In your example, this
is probably overkill as you're only dealing with one class: but Terry
did provide a nice example of when it could fail.

Another (convoluted) example:

class mystr(str):
    def lower(self):
        return self.upper()

>>> s = mystr('abc')
>>> s.lower()
'ABC'

>>> lower = methodcaller('lower')
>>> lower(s)
'ABC'

>>> str.lower(s)
'abc'

^^^ Most likely incorrect

It also adds a further bit of flexibility (which can be emulated with
functools.partial admittedly):

split_tab = methodcaller('split', '\t')
split_comma = methodcaller('split', ',')

... etc ...

Cheers,

Jon.





More information about the Python-list mailing list