Creating object attributes

Discussion in 'Python' started by Greg Lindstrom, Jul 22, 2004.

  1. 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

    "We are the music makers, and we are the dreamers of dreams" W.W.
    Greg Lindstrom, Jul 22, 2004
    #1
    1. Advertising

  2. Greg Lindstrom

    Larry Bates Guest

    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" <> wrote in message
    news:...
    > 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
    >
    > "We are the music makers, and we are the dreamers of dreams" W.W.
    >
    >
    Larry Bates, Jul 22, 2004
    #2
    1. Advertising

  3. Greg Lindstrom

    Peter Otten Guest

    Greg Lindstrom wrote:

    > 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
    Peter Otten, Jul 23, 2004
    #3
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Andrew Ng
    Replies:
    1
    Views:
    344
    Gerbrand van Dieijen
    Oct 12, 2003
  2. Max
    Replies:
    1
    Views:
    471
    Joe Kesselman
    Sep 22, 2006
  3. P4trykx
    Replies:
    2
    Views:
    1,793
    bruce barker
    Jan 31, 2007
  4. shuvro
    Replies:
    3
    Views:
    252
    Terry Reedy
    May 18, 2010
  5. Ben Sizer
    Replies:
    11
    Views:
    215
    Steven D'Aprano
    Mar 8, 2013
Loading...

Share This Page