在 Python 中对协议使用 PEAK
2007-03-30 12:25:16 来源:WEB开发网核心提示: lispy.py PyProtocol 定义from protocols import *from cStringIO import StringIO# Like unicode, & even support objects that don't explicitly suppo
lispy.py PyProtocol 定义
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)
更多精彩
赞助商链接