[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