def __init__(self): self._mapping = CodeLookup() self._params = dict()
class Reader( object ): @classmethod def new( cls, classname, **params ): for c in cls.__subclasses__(): if c.__name__ == classname: r = c() r.setParameters( **params ) return r raise Error("AddressData reader type " + classname + " is not defined") @classmethod def params( cls ): return [] def __init__(self): self._mapping = CodeLookup() self._params = dict() # Abstract functions - must be overridden def load(self,filename): raise Error("Reader.load not defined for " + self.__class__.__name__) def reset( self ): raise Error("Reader.reset not implemented for ".self.__class__.__name__) # nextAddress returns srcid, roadname, roadnumber, location def nextAddress( self ): raise Error("Reader.nextAddress not implemented for ".self.__class__.__name__) # Define parameters to be used by a subclass def setParameters( self, **params ): assert isinstance(params,dict) self._params = params def param( self, name, dflt=None ): return self._params.get(name,dflt) # Define a mapping function to be used by a subclass def setMappingSource( self, mapping ): """ Define an object used for looking up values Object must implement def lookup( self, type, key, dflt=None ) """ assert isinstance(mapping,CodeLookup) self._mapping = mapping def lookup( self, type, key, default=None ): return self._mapping.lookup(type,key,default) # Generator to return addresses def addresses( self ): while True: a = self.nextAddress() if a == None: break assert isinstance(a,AddressData) yield a # Creation and evaluation of definitions def loadDefinition( self, paramname ): definition = self.param(paramname,'') defn = None try: defn = FieldEvaluator(definition,self.lookup).evaluator() except: raise Error('Invalid '+paramname+' field definition "' + definition + '"') return defn def evaluateDefinition( self, func, definition, dflt='' ): " Requires a function(x) returning the value of field x" if not definition: return dflt return definition(func)