[Python-3000] Generic functions
Nick Coghlan
ncoghlan at gmail.com
Tue Apr 4 12:12:35 CEST 2006
Ian Bicking wrote:
> As an alternative to adaptation, I'd like to propose generic functions.
> I think they play much the same role, except they are much simpler to
> use and think about.
Unfortunately the rules for choosing *which* implementation to dispatch to,
even if restricting things to concrete types only, are necessarily complex.
As Walter pointed out, the deliberately simplistic sample code elsewhere in
this thread dispatches to a different method depending on order of
registration and hashing idiosyncrasies.
To fix that, you either have to stop permitting subclasses of registered
argument types, or else you have to define the idea of a "closest" signature
match, at which point you've been forced to throw "simple" right out the window.
Given this type hierarchy:
A
B C
D E F
and a call containing (D(), E(), F()), is the type signature (B, B, C) a
closer match than the signature (A, E, F)?
In a certain sense, an adapting protocol is just a generic function that only
permits dispatch of single argument functions based on type of that argument -
as such, adaptation is necessarily simpler than full generic function support.
To go back to Ian's pretty printing example, here's an implementation of
pretty printing using an adaptation protocol:
------------pprint.py-----------------
import adaptation
class IPrettyPrintable(adaptation.Protocol):
def pformat(self, indent, width, depth):
"""Return the pretty representation of the object"""
# Register known pretty printer functions (e.g. for list and dict) here
class PrettyPrinter:
# Other normal pretty printer methods go here
def pformat(self, obj):
printable = IPrettyPrintable(obj) # Permit extension to new types
return printable.pformat(self.indent, self.width, self.depth)
--------------------------------------
Now all another class would need to do to make itself pretty printable:
------------mymodule.py-----------------
from pprint import IPrettyPrintable
class MyClass(object):
def pformat(self, indent, width, depth):
# Do the pretty print operation
# based on self
return formatted
IPrettyPrintable.register_type(MyClass) # No adapter needed
--------------------------------------
Suppose, however, I wanted to pretty print someone else's class. That's just
as easy:
------------mymodule.py-----------------
from pprint import IPrettyPrintable
from their_module import TheirClass
class MyAdapter(object):
def __init__(self, obj):
self.obj = obj
def pformat(self, indent, width, depth):
# Do the pretty print operation
# based on self.obj
return formatted
IPrettyPrintable.register_type(TheirClass, MyAdapter)
--------------------------------------
Cheers,
Nick.
--
Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia
---------------------------------------------------------------
http://www.boredomandlaziness.org
More information about the Python-3000
mailing list