Package parser_course :: Package small_parsers :: Module supertuple
[hide private]
[frames] | no frames]

Source Code for Module parser_course.small_parsers.supertuple

  1  ## From 
  2  ## Python Cookbook 2nd Edition 
  3  ## Martelli, Martelli, Ascher  Copyright 2005 
  4  ## ISBN: 0-596-00797-3 
  5  ## http://www.oreilly.com/catalog/pythonian2 
  6  ## from cb_6_7_sol_1.py 
  7   
  8  # use operator.itemgetter if we're in 2.4, roll our own if we're in 2.3 
  9  import sys 
 10  try: 
 11      from operator import itemgetter 
 12  except ImportError: 
13 - def itemgetter(i):
14 def getter(self): return self[i] 15 return getter
16
17 -def itemsetter(i):
18 def setter(self,val): self[i]=val 19 return setter
20 -def superTuple(typename, *attribute_names):
21 """ create and return a subclass of `tuple', with named attributes 22 Example: 23 >>> Point = supertuple.superTuple('Point','x','y') 24 >>> Point 25 <class 'supertuple.Point'> 26 >>> p = Point(1,2,3) # wrong number of fields 27 Traceback (most recent call last): 28 ... 29 TypeError: Point exactly 2 arguments (3 given) 30 >>> p = Point(1,2) # Do it right this time. 31 >>> p 32 Point(1,2) 33 >>> print p.x, p.y 34 1 2 35 """ 36 # make the subclass with appropriate __new__ and __repr__ specials 37 nargs = len(attribute_names) 38 class supertup(tuple): 39 __slots__ = () # save memory, we don't need per-instance dict 40 def __new__(cls, *args): 41 if len(args) != nargs: 42 raise TypeError, '%s takes exactly %d arguments (%d given)' % ( 43 typename, nargs, len(args)) 44 return tuple.__new__(cls, args)
45 def __repr__(self): 46 return '%s(%s)' % (typename, ', '.join(map(repr, self))) 47 # add a few key touches to our new subclass of `tuple' 48 for index, attr_name in enumerate(attribute_names): 49 setattr(supertup, attr_name, property(itemgetter(index),itemsetter(index))) 50 supertup.__name__ = typename 51 return supertup 52 53 54
55 -def superTuplePlus(typename, *attribute_names):
56 """ create and return a subclass of `tuple', with named attributes 57 Example: 58 >>> Point = supertuple.superTuplePlus('Point','x','y') 59 >>> Point 60 <class 'supertuple.Point'> 61 >>> p = Point(x=1,y=2,z=3) # wrong number of fields 62 Traceback (most recent call last): 63 ... 64 TypeError: Point exactly 2 arguments (3 given) 65 >>> p = Point(x=1,y=2) # Do it right this time. 66 >>> p 67 Point(1,2) 68 >>> print p.x, p.y 69 1 2 70 """ 71 nargs = len(attribute_names) 72 class supertup(tuple): 73 __slots__ = () # save memory, we don't need per-instance dict 74 def __new__(cls, *args, **kwds): 75 args_copy = list(args) 76 if len(kwds) + len(args) != nargs: 77 raise TypeError, '%s takes exactly %d arguments (%d given)' % ( 78 typename, nargs, len(args)+len(kwds)) 79 errs =[] 80 for index in range(len(args),len(attribute_names)): 81 attr_name = attribute_names[index] 82 try: 83 args_copy.append(kwds[attr_name]) 84 del kwds[attr_name] 85 except KeyError: 86 errs.append('Missing %s attribute: %s\n ' % (typename, attr_name)) 87 if kwds: 88 ## Missing attributes iff some keywords left over 89 if args: 90 errs.append('Type %s: %s filled by positional arguments\n ' % (typename,attribute_names[:len(args)])) 91 errs = ''.join(errs) 92 raise TypeError, errs+'Unknown or duplicate %s keyword arguments: %s' % (typename, kwds.keys()) 93 else: 94 return tuple.__new__(cls, args_copy)
95 def __repr__(self): 96 return '%s(%s)' % (typename, ', '.join(map(repr, self))) 97 def display (self): 98 for attr_name in attribute_names: 99 print '%s: %s' % (attr_name, getattr(self, attr_name)) 100 # add a few key touches to our new subclass of `tuple' 101 for index, attr_name in enumerate(attribute_names): 102 setattr(supertup, attr_name, property(itemgetter(index),itemsetter(index))) 103 supertup.__name__ = typename 104 return supertup 105