[Types-sig] QueryProtocol
Clark C. Evans
cce@clarkevans.com
Wed, 21 Mar 2001 18:24:14 -0500 (EST)
On Wed, 21 Mar 2001, Clark C. Evans wrote:
> However, "adapt" could easly call "check" for the trivial
> case, or the functions could be merged with an argument
> (checkonly=true/false).
Here is the "merged" version where check_only is an
optional argument to adapt. Imagine the operator,
a isa b -> adapt(a,b,check_only=true)
--------------------------------------------------------
adapter/__init__.py
--------------------------------------------------------
import types
def adapt(obj,ident,check_only=0):
# check to see if the current object is ok as is
if obj is ident: return obj
if type(obj) is ident: return obj
if type(obj) is type(ident): return obj
if type(ident) is types.ClassType:
if type(obj) is types.InstanceType:
if isinstance(obj,ident): return obj
if type(obj) is types.ClassType:
if issubclass(obj,ident): return obj
# the obj may have the answer, so ask it about the ident
adapt = getattr(obj, '__adapt__',None)
if adapt:
retval = adapt(ident,check_only)
if retval: return retval
# the ident may have the answer, so ask it about the obj
# some code here for a class, type, or interface,
# or whatever to check to see if it can adapt the
# class. Unfortunately, calling __adapt__ won't
# work exactly here... we could add another
# argument, "forward"...
--------------------------------------------------------------
adapter/example.py
--------------------------------------------------------------
class EggsOnly: # an unrelated class/interface
def eggs(self,str): print "eggs!" + str
class HamOnly: # used as an interface, no inhertance
def ham(self,str): pass
def _bugger(self): pass # irritating a private member
class SpamOnly: # a base class, inheritance used
def spam(self,str): print "spam!" + str
class EggsSpamAndHam (SpamOnly):
def ham(self,str): print "ham!" + str
def __adapt__(self,ident,check_only):
if ident is HamOnly:
return self # implements HamOnly implicitly, no _bugger
if ident is EggsOnly and not check_only:
return EggsOnly() # Knows how to create the eggs!
------------------------------------------------------------------
testadapter.py
------------------------------------------------------------------
import adapter.example
from adapter import adapt
def testadapter():
x = adapter.example.EggsSpamAndHam()
adapt(x,adapter.example.SpamOnly).spam("Ni!")
adapt(x,adapter.example.EggsOnly).eggs("Ni!")
adapt(x,adapter.example.HamOnly).ham("Ni!")
adapt(x,adapter.example.EggsSpamAndHam).ham("Ni!")
#
# imagine operator syntax for check_only:
#
# if x isa adapter.example.SpamOnly: print "SpamOnly"
#
if (x,adapter.example.SpamOnly,1): print "SpamOnly"
if (x,adapter.example.EggsOnly,1): print "EggsOnly"
if (x,adapter.example.HamOnly,1): print "HamOnly"
if (x,adapter.example.EggsSpamAndHam,1): print "EggsAndSpam"
if (x,adapter.example.KnightsWhoSayNi,1): print "NightsWhoSayNi"
adapt(x,adapter.example.KnightsWhoSayNi,1).spam("Ni!")
--------------------------------------------------------------------
example run
--------------------------------------------------------------------
>>> import testadapter
>>> testadapter.testadapter()
spam!Ni!
eggs!Ni!
ham!Ni!
ham!Ni!
SpamOnly
EggsOnly
HamOnly
EggsAndSpam
Traceback (innermost last):
File "<interactive input>", line 1, in ?
File "c:\work\testadapter.py", line 13, in testadapter
if (x,adapter.example.KnightsWhoSayNi,1): print "NightsWhoSayNi"
AttributeError: KnightsWhoSayNi