from protocols import * from cStringIO import StringIO # Like unicode, & even support objects that don't explicitly support ILisp ILisp = protocolForType(unicode, ['__repr__'], implicit=True) # Class for interface, but no methods specifically required class ISeq(Interface): pass # Class for interface, extremely simple mapping interface class IMap(Interface): def items(): "A requirement for a map is to have an .items() method" # Define function to create an Lisp like representation of a mapping def map2Lisp(map_, prot): out = StringIO() for k,v in map_.items(): out.write("(%s %s) " % (adapt(k,prot), adapt(v,prot))) return "(MAP %s)" % out.getvalue() # Use this func to convert an IMap-supporting obj to ILisp-supporting obj declareAdapter(map2Lisp, provides=[ILisp], forProtocols=[IMap]) # Note that a dict implements an IMap interface with no conversion needed declareAdapter(NO_ADAPTER_NEEDED, provides=[IMap], forTypes=[dict]) # Define and use func to adapt an InstanceType obj to the ILisp interface from types import InstanceType def inst2Lisp(o, p): return "(CLASS '(%s) %s)" % (o.__class__.__name__, adapt(o.__dict__,p)) declareAdapter(inst2Lisp, provides=[ILisp], forTypes=[InstanceType]) # Define a class to adapt an ISeq-supporting obj to an IMap-supporting obj class SeqAsMap(object): advise(instancesProvide=[IMap], asAdapterForProtocols=[ISeq] ) def __init__(self, seq, prot): self.seq = seq self.prot = prot def items(self): # Implement the IMap required .items() method return enumerate(self.seq) # Note that list, tuple implement an ISeq interface w/o conversion needed declareAdapter(NO_ADAPTER_NEEDED, provides=[ISeq], forTypes=[list, tuple]) # Define a lambda func to adapt str, unicode to ILisp interface declareAdapter(lambda s,p: "'(%s)" % s, provides=[ILisp], forTypes=[str,unicode]) # Define a class to adapt several numeric types to ILisp interface # Return a string (ILisp-supporting) directly from instance constructor class NumberAsLisp(object): advise(instancesProvide=[ILisp], asAdapterForTypes=[long, float, complex, bool] ) def __new__(klass, val, proto): return "(%s %s)" % (val.__class__.__name__.upper(), val)
(编辑:aniston)
|