This is my own experiment with adapters and interfaces. I could not join the SourceForge project, and I dont know how things are being implemented right now. Use as you wish (even as a example of don't-do-this <wink>). Warning: this is work in progress, and as such, there are a *lot* of things that could be improved, some of them quite obvious. My objective with this example is just to show some ideas that I had while reading all the material in the past weeks. There are two basic implementations of "interfaces", named Interface_V1 and Interface_V2. Basically they represent two different methods to write a interface specification using Python 2.0 as it is today. Enjoy <wink> or flame <duck>. SAMPLE OUTPUT: >>> f = FakeSequence([1,2,3,4]) >>> for i in f: print i ... Traceback (innermost last): File "<interactive input>", line 1, in ? AttributeError: 'FakeSequence' instance has no attribute '__getitem__' >>> for i in f.__adapt__(I1_Sequence): print i ... 1 2 3 4 >>> for i in f.__adapt__(I2_Sequence): print i ... 1 2 3 4 >>> CODE: """ Adapter proof-of-concept (c) 2001 Carlos Ribeiro - cribeiro at mail.inet.com.br Released in public domain for use "as-is" """ from types import * #----------------------------------------------------------------------- class CAnyType: """ AnyType can be used to specify a parameter of 'any type'""" def __cmp__(self, other): return (type(other) != TypeType) def __rcmp__(self, other): return (type(other) != TypeType) AnyType = CAnyType() #----------------------------------------------------------------------- class Interface_V1: """ base class for interface specification """ __methodlist__ = [] class I1_Sequence(Interface_V1): """ Protocol to implement sequence-like objects """ __methodlist__ = ['__len__', '__getitem__', '__setitem__', '__delitem__'] def __len__ (self): pass def __getitem__(self, key): pass def __setitem__(self, key, value): pass def __delitem__(self, key): pass #----------------------------------------------------------------------- class Interface_V2: """ base class for interface specification """ pass class I2_Sequence(Interface_V2): """ Protocol to implement sequence-like objects """ __len__ = ((), (IntType)) __getitem__ = ((IntType,), (AnyType,)) __setitem__ = ((IntType,AnyType), ()) __delitem__ = ((IntType,), ()) #----------------------------------------------------------------------- class Adapter: """ empty class that can be used to build any kind of adapter """ pass def MakeInterfaceAdapter_V1(interface, object, rename_map = {}): """ Returns a protocol adapter for an object supporting the interface. By default it will map methods in the object to the methods with the same name in the interface/protocol. The optional parameter 'rename_map' is a map[interface_name] = object_name, that contains all methods that need to be renamed. """ a = Adapter() for imethod in interface.__methodlist__: # check the rename list if rename_map.has_key(imethod): omethod = rename_map[imethod] else: omethod = imethod setattr(a, imethod, getattr(object, omethod)) return a def MakeInterfaceAdapter_V2(interface, object, rename_map = {}): """ Returns a protocol adapter for an object supporting the interface. By default it will map methods in the object to the methods with the same name in the interface/protocol. The optional parameter 'rename_map' is a map[interface_name] = object_name, that contains all methods that need to be renamed. """ a = Adapter() for imethod, iparam in interface.__dict__.items(): # check to see if it's a valid method definition if (type(iparam) is TupleType) and (len(iparam) == 2): # check the rename list if rename_map.has_key(imethod): omethod = rename_map[imethod] else: omethod = imethod setattr(a, imethod, getattr(object, omethod)) return a #----------------------------------------------------------------------- class FakeSequence: """ Acts like a sequence, but it's not a UserList Does not make any error check, etc. """ # dictionary to make the call to MakeInterfaceAdapter cleaner ir_sequence = { '__len__' :'seqlen', '__getitem__':'seqgetitem', '__setitem__':'seqsetitem', '__delitem__':'seqdelitem' } def __init__(self, p_list): self.list = p_list def seqlen(self, p_list): return (self.list) def seqgetitem(self, i): return self.list[i] def seqsetitem(self, i, p_value): self.list[i] = p_value def seqdelitem(self, i): del(self.list[i]) def __adapt__(self, protocol): if protocol == I1_Sequence: return MakeInterfaceAdapter_V1(protocol, self, self.ir_sequence) elif protocol == I2_Sequence: return MakeInterfaceAdapter_V2(protocol, self, self.ir_sequence) else: return None #----------------------------------------------------------------------- Carlos Ribeiro
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4