Creating object attributes

Peter Otten __peter__ at web.de
Fri Jul 23 09:30:03 CEST 2004


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






More information about the Python-list mailing list