Dynamic Class Creation

Chris Rebert clp2 at rebertia.com
Tue Mar 16 02:18:54 EDT 2010


On Mon, Mar 15, 2010 at 11:01 PM, Josh English
<joshua.r.english at gmail.com> wrote:
> I have a large program with lots of data stored in XML. I'm upgrading
> my GUI to use ObjectListView, but with my data in XML, I don't have
> regular objects to interact with the OLV. I do have an XML validator
> that defines the structure of the XML elements, and I'm trying to
> dynamically create a class to wrap the XML element.
>
> So, an element like:
>
> <market code="WotF">
> <title>Writers of the Future</title>
> </market>
>
> I want to create a class like:
>
> class Market(object):
>    def __init__(self, elem):
>        self._elem = elem
>
>    def get_code(self):
>        return self._elem.get('code')
>
>    def set_code(self, value):
>        self._elem.set('code', value)
>
>    def get_title(self):
>        return self._elem.find('title').text
>
>    def set_title(self, value):
>        node = self._elem.find('title')
>        node.text = value
>
> Naturally, I don't want to hand code this for every interface but
> would like to create them dynamically. (The laziness of programming, I
> guess.)
>
> I have tried several solutions that I found on various forums, but
> they are all several years old.
>
> Questions:
>
> What's the best way to create these helper methods?

Nested functions:

def make_attr_getset(name):
    def get(self):
        return self._elem.get(name)

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

get_code, set_code = make_attr_getset('code')

def make_subelement_getset(name):
    def get(self):
        return self._elem.find(name).text

    def set(self, value):
        node = self._elem.find(name)
        node.text = value
    return get, set

get_title, set_title = make_subelement_getset('title')

> How can I attach them to the class and have it run?

Use properties and setattr():

class Market(object):
    def __init__(... #same as before

setattr(Market, 'code', property(get_code, set_code))
setattr(Market, 'title', property(get_title, set_title))

m = Market(the_XML)
print m.title #=> Writers of the Future
m.title = "Writers of the Past"
print m.code #=> WotF
m.code = "WofP"

Cheers,
Chris
--
http://blog.rebertia.com



More information about the Python-list mailing list