I am parsing a binary log file. The log file is formatted as follows: every 10 bytes is a record, the first byte of the record is the record type, the next 5 bytes are a timestamp and the last 4 bytes are record type specific data.
Currently I am doing the following:
# read the input binary stream
with open(filename, mode='rb') as trace_stream:
# create an empty list of trace records
trace = []
# iterate over each record in the binary stream
for record_type, record_data in yield_record(trace_stream,
size=RECORD_LENGTH):
# create a new record instance
if record_type == SEN_RECORD:
new_record = sen_record(record_data)
elif record_type == DSP_RECORD:
new_record = dsp_record(record_data)
elif record_type == USO_RECORD:
new_record = uso_record(record_data)
elif record_type == SDM_RECORD:
new_record = sdm_record(record_data)
elif record_type == DOC_RECORD:
new_record = doc_record(record_data)
elif record_type == DAT_RECORD:
new_record = dat_record(record_data)
elif record_type == LAT_RECORD:
new_record = lat_record(record_data)
elif record_type == SWI_RECORD:
new_record = swi_record(record_data)
elif record_type == FTL_RECORD:
new_record = ftl_record(record_data)
# append this new record to our trace
trace.append(new_record)
Where sen_record, dsp_record, uso_record etc. are all sub-classes of a generic record class
What I would like to do is the following:
# read the input binary stream
with open(filename, mode='rb') as trace_stream:
# create an empty list of trace records
trace = []
# iterate over each record in the binary stream
for record_type, record_data in yield_record(trace_stream,
size=RECORD_LENGTH):
new_record = record(record_data)
trace.append(new_record)
And then have the record class constructor do the work of determining what type of record it is and creating the appropriate class instances. Ideally my “main” routine shouldn’t need to know about the record types?
Is there any way to do this?
It would be simpler just to store the mapping
somewhere, and use that to look up the correct record type. (Note that you can do this, because classes are just objects, so you can put them in a dictionary.)
Specifically, you’d do
There are more complicated ways of doing this (say if you wanted the subclasses to be created dynamically and automatically registered with their superclass upon creation), but there’s no need to employ them in your situation.