Anticipating that derived classes may do almost anything differently from each other, we try to restrict the code in the constructor to contain only operations that are always the same. Accordingly, the constructor calls a few generalized methods, any of which can be replaced in a derived class.
# - - - B a s e C o m p i l e r . _ _ i n i t _ _ - - - def __init__(self, fileName, stationSet, speciesSet): '''Constructor for BaseCompiler. '''
One thing we'll always do is to remember the station and species authority objects, and initialize all the internal state items.
#-- 1 -- self.fileName = fileName self.stationSet = stationSet self.speciesSet = speciesSet self.pageHeader = None self.prefix = None self.oldEncounter = None
Next we need to analyze the
insure that it conforms to the batch file naming scheme.
This step will also set the
.station state items. See Section 19.4, “
BaseCompiler.parseFileName(): Parse the
batch file name”.
#-- 2 -- # [ if self.fileName conforms to the batch file naming scheme and # represents a multi-station location in self.stationSet -> # self.location := a Location object representing that # location # self.station := None # self.year := year from self.fileName # else if self.fileName conforms to the batch file naming # scheme and represents a single-station location in # self.stationSet -> # self.location := None # self.station := a Station object representing that # station # self.year := year from self.fileName # else -> # Log() +:= error message(s) # raise ValueError ] self.parseFileName()
All that remains is to attempt to open the input file for
reading, using the
Scan class. The
callback keyword argument is used to report our
current band size and page number as part of each error
message; see Section 19.8, “
This is an interesting use of Python's “bound
method” feature. The reference to
self.scanCallback gives us an object of function
type, but the current value of “
self” is bound into it. Hence, it can be called by
scan object, even though
scan has no idea where to find the
BaseCompiler object that contains the band
size and page number that we need to see in any syntax
#-- 3 -- # [ if self.fileName can be opened for reading -> # self.scan := a Scan object pointing at the start # of that file # else -> # Log() +:= error message(s) # raise ValueError ] try: self.scan = Scan(self.fileName, callback=self.scanCallback) except IOError, detail: message = ("Can't open input file '%s': %s" % (self.fileName, detail)) Log().error(message) raise ValueError, message
Processing will continue when the caller calls our