Dynamically create a class (or class instance) and its attributes?

Discussion in 'Python' started by Robert Oschler, Jul 27, 2004.

  1. Hello,

    I am a Python newbie (by experience, not chronologically :) ), so if any of
    this doesn't make sense my apologies in advance.

    I am reading the chapter in The Python Cookbook on databases and the MySQLdb
    module. In it they show an example of a recipe that lets you access fields
    in a MySQL row by name rather than by column number. For example, given a
    MySQL row object from a fetchone() call:

    employee_name = sqlrow[field_dict['empname']]

    To make the syntax easier and clearer, I would like to create a Python class
    instance that would allow me to access the fields in the MySQL row as
    attributes of a class created dynamically from the row structure. For
    example:

    employee_name = ez_sqlrow.empname

    What would be the best way to create such a class or class instance? Any
    code examples you have would be welcome.

    Thanks
    --
    Robert
    Robert Oschler, Jul 27, 2004
    #1
    1. Advertising

  2. This may work.

    <pre>

    class Dyn:
    '''Dynamic class.
    '''
    def __init__(self, **kwds):
    self.set(**kwds)

    def set(self, **kwds):
    for a, v in kwds.iteritems():
    setattr(self, a, v)


    # all attr defined at creation
    # time with an initial value
    c = Dyn(a1=1, a2=2, a3=3)

    # more attr can be added
    c.set(a4=4, a5=5)

    # attr can be changed
    c.a1=10
    c.set(a1=20)

    </pre>

    /Jean Brouwers




    In article <nblNc.19344$>, Robert Oschler
    <no_replies@fake_email_address.invalid> wrote:

    > Hello,
    >
    > I am a Python newbie (by experience, not chronologically :) ), so if any of
    > this doesn't make sense my apologies in advance.
    >
    > I am reading the chapter in The Python Cookbook on databases and the MySQLdb
    > module. In it they show an example of a recipe that lets you access fields
    > in a MySQL row by name rather than by column number. For example, given a
    > MySQL row object from a fetchone() call:
    >
    > employee_name = sqlrow[field_dict['empname']]
    >
    > To make the syntax easier and clearer, I would like to create a Python class
    > instance that would allow me to access the fields in the MySQL row as
    > attributes of a class created dynamically from the row structure. For
    > example:
    >
    > employee_name = ez_sqlrow.empname
    >
    > What would be the best way to create such a class or class instance? Any
    > code examples you have would be welcome.
    >
    > Thanks
    Jean Brouwers, Jul 27, 2004
    #2
    1. Advertising

  3. Robert Oschler

    Peter Otten Guest

    Robert Oschler wrote:

    > To make the syntax easier and clearer, I would like to create a Python
    > class instance that would allow me to access the fields in the MySQL row
    > as attributes of a class created dynamically from the row structure. For
    > example:
    >
    > employee_name = ez_sqlrow.empname


    Here is one way:

    import itertools

    class Record:
    def __init__(self, row):
    assert len(row) == len(self.names)
    self._row = row
    def __getitem__(self, index):
    return self._row[index]
    def __setitem__(self, index, value):
    self._row[index] = value
    def __iter__(self):
    return itertools.izip(self.names, self._row)
    def __repr__(self):
    return "%s(%s)" % (self.__class__.__name__,
    ", ".join(["%s=%r" % nv for nv in self]))

    def makeProperty(index):
    def get(self):
    return self[index]
    def set(self, value):
    self[index] = value
    return property(get, set)

    def makeClass(classname, fieldnames, Base=Record):
    class Record(Base):
    names = fieldnames
    Record.__name__ = classname

    for index, name in enumerate(fieldnames):
    setattr(Record, name, makeProperty(index))
    return Record

    if __name__ == "__main__":
    Person = makeClass("Person", ["firstname", "lastname", "email"])
    r = Person(["Robert", "Oschler", "not provided"])
    print r.firstname
    r.email = ""
    print r.email
    print "%s %s" % tuple(r[:2])
    print r

    which is actually a variant of something I posted a few days ago. Or you go
    with SQLObject.(Am I repeating myself? Am I repeating myself :)

    Peter
    Peter Otten, Jul 27, 2004
    #3
  4. On Tue, 27 Jul 2004, Robert Oschler wrote:

    > For example, given a MySQL row object from a fetchone() call:
    >
    > employee_name = sqlrow[field_dict['empname']]
    >
    > To make the syntax easier and clearer, I would like to create a Python class
    > instance that would allow me to access the fields in the MySQL row as
    > attributes of a class created dynamically from the row structure. For
    > example:
    >
    > employee_name = ez_sqlrow.empname
    >
    > What would be the best way to create such a class or class instance? Any
    > code examples you have would be welcome.


    The other respondents have recommended using setattr(), but here's a way
    that will work completely dynamically:

    class ez_sql(object):

    def __init__(self,sqlrow):
    self._sqlrow = sqlrow

    def __getattr__(self,a):
    try:
    return self._sqlrow[fielddict[a]]
    except (IndexError,KeyError),e:
    raise AttributeError,e

    def __setattr__(self,a,v):
    try:
    self._sqlrow[fielddict[a]] = v
    except KeyError:
    self.__dict__[a] = v

    This is a bit slower than using setattr(), but might save a good deal of
    memory (especially if you keep the SQL rows around in another form).
    Christopher T King, Jul 27, 2004
    #4
    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. Gerard Flanagan
    Replies:
    3
    Views:
    443
    Terry Hancock
    Nov 19, 2005
  2. thunk
    Replies:
    1
    Views:
    307
    thunk
    Mar 30, 2010
  3. thunk
    Replies:
    0
    Views:
    472
    thunk
    Apr 1, 2010
  4. thunk
    Replies:
    14
    Views:
    614
    thunk
    Apr 3, 2010
  5. Kedar Mhaswade
    Replies:
    1
    Views:
    122
    Gary Wright
    Jan 25, 2011
Loading...

Share This Page