Yet Another PEP: Query Protocol Interface or __query__
Clark C. Evans
cce at clarkevans.com
Tue Mar 27 04:15:34 EST 2001
On Mon, 26 Mar 2001, Carlos Ribeiro wrote:
> 6) We can solve (5) using a 'proxy', or 'adapter'.
Ahh, it finally got though my dence skull what you
are proposing -- more of a proxy mechanism, which
has a further constraint, not only must the expected
methods be mapped, but *only* the expected methos
are to be mapped.
> EXAMPLE
>
> Assume that we have these protocols:
>
> a) protocol 'IntegerDivision'
> supports the __div__() method for integer division
> b) protocol 'FloatDivision'
> supports the __div__() method for floating point division
>
> #----------------------------------------------------------------------
>
> class Protocol:
> """ empty class that can be used for all protocol adaptation """
> pass
>
> def MakeProtocolDefault(protocol_methods, adaptee):
> """ Returns the default protocol adapter for an object
> The default uses the same name for all methods in the protocol
> and in the object instance that is being adapted
> """
> p = Protocol()
> for pm in protocol_methods:
> om = getattr(adaptee, pm)
> setattr(p, pm, om)
> return p
>
> def MakeProtocol(protocol_methods, object_methods):
> """ Returns the a protocol adapter for an object, mapping
> each protocol_method to a object_method
> """
> p = Protocol()
> for pm, om in zip(protocol_methods, object_methods):
> setattr(p, pm, om)
> return p
>
> class Number:
> """ supports both protocols: 'IntegerDivision' & 'FloatDivision' """
> def __init__(self, p_value):
> self.value = p_value
>
> def div_int(self, b):
> # integer division
> return int(self.value)/int(b)
>
> def div_float(self, b):
> # floating point division
> return float(self.value)/float(b)
>
> def __adapt__(self, protocol):
> if protocol == 'IntegerDivision':
> return MakeProtocol(['__div__'], [self.div_int])
> elif protocol == 'FloatDivision':
> return MakeProtocol(['__div__'], [self.div_float])
> else:
> return None
>
> #----------------------------------------------------------------------
>
> >>> n = Number(2)
> >>> in = n.__adapt__('IntegerDivision')
> >>> fn = n.__adapt__('FloatDivision')
> >>> in/3
> 0
> >>> fn/3
> 0.66666666666666663
> >>> n.value = 5
> >>> fn/3
> 1.6666666666666667
> >>>
>
> #----------------------------------------------------------------------
Very Neat.
;) Clark
More information about the Python-list
mailing list