"DM" == Dieter Maurer <dieter@handshake.de> writes:
DM> To separate the direction is a good idea. I like it. I am not DM> so sure about the '/' separators. I expect, we will soon get DM> "/" separated object access paths. Then, the use of "/" for a DM> completely different purpose may be confusing. Not sure, that DM> my "[...]" is better in this respect... Zieve does this with ':' sorta like name="foo:int" Another trick from Zieve is the use of comparison classes: __doc__=''' Comparison class for sorting object based on runtime attributes... Steve Spicklemire Silicon Prairie Ventures Inc. steve@spvi.com ''' __version__='$Revision: 1.1.1.1 $'[11:-2] import string import traceback import sys class compClass: # # The idea here is to provide generic sorting... # def __init__(self, sortAttrs = None, raiseExceptions = 0, theClass = None, emptyLast = 1 ): """ set up sort attributes and type conversions....""" self.sortAttrs = [] self.raiseExceptions = raiseExceptions self.emptyLast = emptyLast if sortAttrs: for theAttr in sortAttrs: unbound = 1 if string.find(theAttr,':') != -1: theAttr, theType = string.split(theAttr,':') if self.typeFuncs.has_key(theType): theTypeFunc = self.typeFuncs[theType] elif hasattr(self, theType) and callable(getattr(self, theType)): theTypeFunc = getattr(self, theType) elif theClass and hasattr(theClass, theType) and callable(getattr(theClass, theType)): unbound = 0 theTypeFunc = getattr(theClass, theType) else: theTypeFunc = None else: theTypeFunc = None self.sortAttrs.append((theAttr, theTypeFunc, unbound)) def toInt(self, thing): result = 0 if type(thing) == type(''): try: result = string.atoi(thing) except: if self.raiseExceptions: raise else: result = thing return result def toChar(self, thing): result = '' if type(thing) != type(''): result = str(thing) else: result = thing return result def doComp(self, a, b): if self.emptyLast: # force empty strings last... if type(a) == type('') and type(b) == type(''): if len(a) == 0 and len(b) != 0: return 1 elif len(b) == 0 and len(a) != 0: return -1 if a<b: return -1 if a==b: return 0 return 1 def __call__(self, thingA, thingB): if not self.sortAttrs: return self.doComp(thingA, thingB) result = 0 for theAttr, theFunc, unbound in self.sortAttrs: if hasattr(thingA, theAttr) and hasattr(thingB, theAttr): a = getattr(thingA, theAttr) b = getattr(thingB, theAttr) if theFunc is not None: if unbound: [a,b] = map(lambda o,s=self,t=theFunc:apply(t,(s,o)),[a,b]) # map type conversion onto elements else: [a,b] = map(lambda o,s=self,t=theFunc:apply(t,(o,)),[a,b]) # map type conversion onto elements result = self.doComp(a,b) if result != 0: break return result typeFuncs = { 'int': toInt, 'char': toChar } # type conversion map.... def test(): # # test this sort thingy on some random class.... # class foo: a = 0 b = 0 first = '' def __repr__(self): return '( a->%s, b->%s, first->%s, )[%s]' % ( `self.a`, `self.b`, self.first, id(self)) x = foo() y = foo() z = foo() x.a = '30' x.b = 10 x.first = 'c' y.a = '30' y.b = 100 y.first = 'D' z.a = '200' z.b = 10 z.first = 'E' ccab = compClass(['a:int','b:char']) ccba = compClass(['b:int','a:char']) ccup = compClass(['first:toUpper']) ccabr = compClass(['a:int','b:char'], 1) cc = compClass() list1 = [x,y,z] list2 = ['200','30','300'] list1.sort(ccab) print list1 list1.sort(ccba) print list1 list2.sort(cc) print list2 list1.sort(ccup) print list1 z.a = 'foo' try: list1.sort(ccabr) except ValueError: print "we got the expected exception" gotit = 0 try: list1.sort(ccab) except: gotit = 1 if gotit: print "dang we got the exception we wanted to miss.." else: print "OK.. no exception seen..." if __name__ == '__main__': test()