Creating object attributes

G

Greg Lindstrom

Hello-

I have created a class, FixedLengthRecord.py, that allows me to manipulate
fixed length records in the routines I write. I recently converted it to
read record layouts from an SQL server (it used to read config files) and I
am thinking of making another change to make my code cleaner [WARNING: I am
going to be violating "pure" OO theology...if that offends you, please exit
now].

The heart of the class is a dictionary named "fields" that stores the
current value, length, data type, and default value for the field. Each key
of the dictionary corresponds to a "logical name" read in from the database.
I then have "Get()" and "Set()" methods to -- as you might have guessed --
get and set the values. Other methods are Clear(), Spreadsheet(),
Serialize(), Unserialize(), etc. So, in my application code I might have
something like the following:

myRec = FixedLengthRecord( id='gsl0001', version='1.0', description='This is
my record!')

myRec.Set('first_name', 'Greg') # only field names in the record
layout may be set this way
myRec.Set('last_name', 'Lindstrom')

giver = myRec.Get('first_name')

OK...you get the idea. What I would like to do, or at least consider, is
adding an attribute for each data field value instead of adding it to the
dictionary so I could access my data as follows:

giver = myRec.first_name

I still would use the Set() methods because they insure the fields are less
than or equal to the maximum length allowed. This violates the OO paradigm
of accessor methods, but it cleans up my application code and, since I live
on reality street and not academia, I am interested in how to do it.

So, to simplify the project a tad, suppose I had a tuple of fields.

myFields = ('first_name', 'last_name')

How could I incorporate them into an class "on the fly" to produce the
equivalent of

self.first_name = 'None
self.last_name = None

Are there other ways to handle fixed length records?

Thanks!
--greg

Greg Lindstrom (501) 975-4859
NovaSys Health (e-mail address removed)

"We are the music makers, and we are the dreamers of dreams" W.W.
 
L

Larry Bates

I think we have all done something like what you have done.

I have the class create the attributes dynamically.
Something like (not tested). I'm leaving the fixed record
parsing to you.

class FixedLengthRecord:
def __init__(self, fields):
self.fields=fields
for field in fields:
self.append(field
)
return

def __getitem__(self, key):
try: return self.__dict__[key]
except:
print "Field name '%s' not found in current record" % key
return None

def __setitem__(self, key, value):
if self.__dict__.has_key(key): self.__dict__[key]=value
else:
print "Field name '%s' not found in current record" % key
return

def __call__(self, key):
try: return self.__dict__[key]
except:
print "Field name '%s' not found in current record" % key
return None

def append(self, field, value=None):
if not self.__dict__.has_key(field): self.__dict__[field]=value
else:
print "Field name '%s' already found in current record" % key
return

Then you can do:

myFields = ('first_name', 'last_name')
record=FixedLengthRecord(myFields)
record.append('address')

then these statements work

record.first_name="Greg"
record.last_name="Lindstrom"
record.address="123 Morning Glory Lane"

and

print record('first_name') outputs in "Greg"

Eliminates need for .set and .get methods and grows fieldnames
dynamically.

I hope this is what you were looking for.

Larry Bates
Syscon, Inc.



Greg Lindstrom said:
Hello-

I have created a class, FixedLengthRecord.py, that allows me to manipulate
fixed length records in the routines I write. I recently converted it to
read record layouts from an SQL server (it used to read config files) and I
am thinking of making another change to make my code cleaner [WARNING: I am
going to be violating "pure" OO theology...if that offends you, please exit
now].

The heart of the class is a dictionary named "fields" that stores the
current value, length, data type, and default value for the field. Each key
of the dictionary corresponds to a "logical name" read in from the database.
I then have "Get()" and "Set()" methods to -- as you might have guessed --
get and set the values. Other methods are Clear(), Spreadsheet(),
Serialize(), Unserialize(), etc. So, in my application code I might have
something like the following:

myRec = FixedLengthRecord( id='gsl0001', version='1.0', description='This is
my record!')

myRec.Set('first_name', 'Greg') # only field names in the record
layout may be set this way
myRec.Set('last_name', 'Lindstrom')

giver = myRec.Get('first_name')

OK...you get the idea. What I would like to do, or at least consider, is
adding an attribute for each data field value instead of adding it to the
dictionary so I could access my data as follows:

giver = myRec.first_name

I still would use the Set() methods because they insure the fields are less
than or equal to the maximum length allowed. This violates the OO paradigm
of accessor methods, but it cleans up my application code and, since I live
on reality street and not academia, I am interested in how to do it.

So, to simplify the project a tad, suppose I had a tuple of fields.

myFields = ('first_name', 'last_name')

How could I incorporate them into an class "on the fly" to produce the
equivalent of

self.first_name = 'None
self.last_name = None

Are there other ways to handle fixed length records?

Thanks!
--greg

Greg Lindstrom (501) 975-4859
NovaSys Health (e-mail address removed)

"We are the music makers, and we are the dreamers of dreams" W.W.
 
P

Peter Otten

Greg said:
giver = myRec.Get('first_name')

OK...you get the idea. What I would like to do, or at least consider, is
adding an attribute for each data field value instead of adding it to the
dictionary so I could access my data as follows:

giver = myRec.first_name

I still would use the Set() methods because they insure the fields are
less
than or equal to the maximum length allowed. This violates the OO
paradigm of accessor methods, but it cleans up my application code and,
since I live on reality street and not academia, I am interested in how to

I think from an OO standpoint there is no difference between attributes that
trigger accessor methods and explicit accessor methods. So no, you are not
violating what you call the "theology" and I regard as a useful means to
reduce code interdependence.
So, to simplify the project a tad, suppose I had a tuple of fields.

myFields = ('first_name', 'last_name')

How could I incorporate them into an class "on the fly" to produce the
equivalent of

self.first_name = 'None
self.last_name = None

Here is a simple approach to dynamic generation of properties. It should be
easy to expand, e. g. choose accessors based on the field type.

class Base(object):
def get(self, name):
print "get %s" % name
def set(self, name, value):
print "set %s to %s" % (name, value)

def makeAccessors(cls, name):
def get(self):
return cls.get(self, name)
def set(self, value):
return cls.set(self, name, value)
return get, set

def makeClass(fieldDefs, Base=Base, classname=None):
class Record(Base):
pass
if classname:
Record.__name__ = classname
for fd in fieldDefs:
setattr(Record, fd, property(*makeAccessors(Base, fd)))
return Record

if __name__ == "__main__":
Person = makeClass(["firstname", "surname"])
Customer = makeClass(["cust_id"], Person)
Address = makeClass(["street", "city"], Base, "Address")

c = Customer()
c.firstname = "John"
c.surname = "Neumeyer"
c.surname
c.cust_id

a = Address()
a.street = "Cannery Row"

You might also have a look at SQLObject before you invest more work in your
code.

Peter
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top