[PEAK] pyprotocols

Phillip J. Eby pje at telecommunity.com
Thu Nov 13 19:02:43 EST 2003


At 05:21 PM 11/13/03 -0800, darryl wrote:
>Here's an example from twisted [twisted components] :
>
>from twisted.python import components
>
>class IAmericanSocket(components.Interface):
>    def voltage(self):
>      """Return the voltage produced by this socket object, as an integer.
>      """
>

import protocols

class IAmericanSocket(protocols.Interface):
     def voltage():
        """etc."""


>class AmericanSocket:
>    __implements__ = (IAmericanSocket, )
>    def voltage(self):
>        return 110

class AmericanSocket:
     protocols.advise( instancesProvide=[IAmericanSocket] )
     def voltage(self):
         return 110


>class ForeignSocket:
>    def voltage(self):
>        return 220

No change.


>class AdaptToAmericanSocket(components.Adapter):
>    __implements__ = (IAmericanSocket, )
>    def voltage(self):
>        return self.original.voltage() / 2
>
>components.registerAdapter(
>    AdaptToAmericanSocket,    ForeignSocket,    IAmericanSocket)

class AdaptToAmericanSocket(protocols.Adapter):
     protocols.advise(
         instancesProvide = [IAmericanSocket],
         asAdapterForTypes = [ForeignSocket]
     )
     def voltage(self):
         return self.subject.voltage() / 2

By the way, you aren't required to use the protocols.advise() to declare 
that this class is an adapter factory.  You can also use:

protocols.declareAdapter(
     AdaptToAmericanSocket,
     provides=[IAmericanSocket],
     forTypes=[ForeignSocket]
)

to explicitly register the adapter factory.  Also note that you're not 
required to subclass protocols.Adapter.  Adapter factories can be any 
2-argument callable.


>>>>as = AmericanSocket() fs = ForeignSocket()
>>>>components.implements(as, IAmericanSocket)
>1
>>>>components.implements(fs, IAmericanSocket)
>0

There's a big distinction here in the "PyProtocols way" from what Twisted 
and Zope do.  In PyProtocols there is no built-in way to ask whether an 
object "implements" something.  Instead, you simply adapt it and go 
forward, e.g.:

 >>> adapt(as,IAmericanSocket)
<AmericanSocket instance at 543580485>
 >>> adapt(fs,IAmericanSocket)
<AdaptToAmericanSocket instance at 665894503>
 >>> adapt("foo",IAmericanSocket,"can't adapt")
"can't adapt"

This is a *much* better way to use interfaces than going around asking 
objects if they implement something.  If you think you need to ask an 
object if it implements something, please see:

http://peak.telecommunity.com/protocol_ref/replintrowadapt.html

   and

http://peak.telecommunity.com/protocol_ref/introspect-elim.html

and then, if you're still not convinced, come back and explain what you're 
trying to do.




More information about the PEAK mailing list