On 4/5/06, Tim Hochberg <[EMAIL PROTECTED]> wrote: > It seems like you can chain protocols like that simply by setting up an > appropriate default_adapter method. For example, if we already had a > pprinter protocol, we could define one that subclassed it and customized it: > > class CustomPPrintProtocol(Protocol): > def default_adapter(self, *args): > return pprinter(*args) > hex_pprinter = CustomPPrintProtocol("hex_pprinter") > > @hex_pprinter.register_for(int, long): > def hex_pprint(obj): > return hex(obj) > > > While on the subject of pretty print, I just hacked pretty print to > allow site wide customizations using Protocols. In addition to adding > the protocol class wholesale (it's not on my python path right now), it > took only three lines worth of changes. I added: > > simple_formatter = Protocol('simple_formatter') > simple_formatter.register(repr, object) > > > Near the top and changed _safe_repr to use simple_formatter: > > def _safe_repr(object, context, maxlevels, level): > # .... > rep = simple_formatter(object) # was repr(object) > return rep, (rep and not rep.startswith('<')), False > > > With that in place, I can easily do sitewise changes to stuff like > integer display: > > import pprint > data = ( # From fbots librarybook > "this is a string", [1, 2, 3, 4], ("more tuples", > 1.0, 2.3, 4.5), "this is yet another string" > ) > > pprint.pprint(data) > print > pprint.simple_formatter.register(hex, int, long) > pprint.pprint(data) > > ==> > > ('this is a string', > [1, 2, 3, 4], > ('more tuples', 1.0, 2.2999999999999998, 4.5), > 'this is yet another string') > > ('this is a string', > [0x1, 0x2, 0x3, 0x4], > ('more tuples', 1.0, 2.2999999999999998, 4.5), > 'this is yet another string') > > Nice! > > I expect that with another dozen lines of code I could make custom > pretty printers possible, although the way the customization happens > might be a little kludgy. I'll look into it.
Neat indeed. What I'd like to see is how this changes if we use a generic functions (multiple dispatch) implementation instead of adaptation. Adaptation is pretty much isomorphic with a generic function of one argument (see my blog). But the register_for() method couldn't (shouldn't) interpret multiple arguments as multiple registrations; it should probably take this to match the call signature. Then multiple registrations would slightly more awkward; fortunately they don't have to be as ugly as they were in my earlier post since you can stack them: @hex_pprinter.register_for(int, long) def ... could become @hex_pprinter.register_for(int) @hex_pprinter.register_for(long) def ... I also wonder if the explicit (non-decorator) registration API is rare enough that we could use a single register() method that favors use as a decorator but can be used for explicit registration in a pinch. Then the decorator could look like this: @hex_pprinter.register(int) def ... and explicit registration could be done like this: pprint.simple_formatter.register(int)(hex) pprint.simple_formatter.register(long)(hex) For multiple-argument signatures the call would become e.g. foo.register(int, str, C)(myfunc) which isn't so bad compared to foo.register(myfunc, (int, str, C)) -- --Guido van Rossum (home page: http://www.python.org/~guido/) _______________________________________________ Python-3000 mailing list Python-3000@python.org http://mail.python.org/mailman/listinfo/python-3000 Unsubscribe: http://mail.python.org/mailman/options/python-3000/archive%40mail-archive.com