Another idea for defining the fields in records would be to create a class method that would instantiate the individual fields at instance creation rather than during class definition. This would use less memory when there are no Record objects being used. Storing each Field after it's instantiated into a List, as well as a Dict would remove the necessity for counting the Field instantiation order, since the List would hold them in their proper order.
63 lines
2.1 KiB
Python
63 lines
2.1 KiB
Python
from fields import Field, ValidationError
|
|
import copy
|
|
import pdb
|
|
|
|
class Model(object):
|
|
record_identifier = ' '
|
|
required = False
|
|
|
|
def __init__(self):
|
|
for (key, value) in self.__class__.__dict__.items():
|
|
if isinstance(value, Field):
|
|
# GRAB THE FIELD INSTANCE FROM THE CLASS DEFINITION
|
|
# AND MAKE A LOCAL COPY FOR THIS RECORD'S INSTANCE,
|
|
# OTHERWISE WE'LL END UP WITH VALUES BEING SHARED
|
|
# ACROSS RECORDS.
|
|
src_field = self.__class__.__dict__[key]
|
|
if not src_field.name:
|
|
setattr(src_field, 'name', key)
|
|
setattr(src_field, 'parent_name', self.__class__.__name__)
|
|
self.__dict__[key] = copy.copy(src_field)
|
|
|
|
def __setattr__(self, key, value):
|
|
if hasattr(self, key) and isinstance(getattr(self, key), Field):
|
|
getattr(self, key).value = value
|
|
else:
|
|
# MAYBE THIS SHOULD RAISE A PROPERTY ERROR?
|
|
self.__dict__[key] = value
|
|
|
|
def get_fields(self):
|
|
fields = []
|
|
for key in self.__class__.__dict__.keys():
|
|
attr = getattr(self, key)
|
|
if isinstance(attr, Field):
|
|
fields.append(attr)
|
|
return fields
|
|
|
|
def get_sorted_fields(self):
|
|
fields = self.get_fields()
|
|
fields.sort(key=lambda x:x.creation_counter)
|
|
return fields
|
|
|
|
def validate(self):
|
|
for f in self.get_fields():
|
|
f.validate()
|
|
|
|
try:
|
|
custom_validator = getattr(self, 'validate_' + f.name)
|
|
except AttributeError, e:
|
|
continue
|
|
if callable(custom_validator):
|
|
custom_validator(f)
|
|
|
|
def output(self):
|
|
result = ''.join([self.record_identifier] + [field.get_data() for field in self.get_sorted_fields()])
|
|
if len(result) != 512:
|
|
raise ValidationError("Record result length not equal to 512 bytes")
|
|
return result
|
|
|
|
def read(self, fp):
|
|
for field in self.get_sorted_fields():
|
|
field.read(fp)
|
|
|
|
|