On 23 Aug, 16:57, Tim Daneliuk <tun...@tundraware.com> wrote: > On 8/23/2010 10:35 AM, Jon Clements wrote: > > > > > On 20 Aug, 01:51, Tim Daneliuk <tun...@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...@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. -- http://mail.python.org/mailman/listinfo/python-list