Archive

Posts Tagged ‘__str__’

Using __str__(), print all the attributes of an object

October 30, 2011 Leave a comment

Problem
I have a class which has some attributes. I use the objects of this class as “beans”, i.e. they simply group some data. When I print such an object, I want to see the variables as “name=value” pairs but I don’t want to code that manually. I want to iterate all the attributes and produce such a string representation of the object.

Solution
Attributes are stored in a dictionary-like __dict__ in the object. Furthermore, __dict__ contains only the user-provided attributes. Read more here. Thus, all we have to do is printing __dict__:

def __str__(self):
    sb = []
    for key in self.__dict__:
        sb.append("{key}='{value}'".format(key=key, value=self.__dict__[key]))

    return ', '.join(sb)

def __repr__(self):
    return self.__str__() 

A full example
Read an RSS feed and store item data in beans. Print the beans.

#!/usr/bin/env python

import untangle

XML = 'http://planet.python.org/rss20.xml'

from jabbapylib.text.ascii import unicode_to_ascii

class Item:
    def __init__(self, item):
        self.title = unicode_to_ascii(item.title.cdata)
        self.link = item.link.cdata

    def __str__(self):
        sb = []
        for key in self.__dict__:
            sb.append("{key}='{value}'".format(key=key, value=self.__dict__[key]))

        return ', '.join(sb)

    def __repr__(self):
        return self.__str__()

def main():
    li = []

    o = untangle.parse(XML)
    for item in o.rss.channel.item:
        if item.link.cdata:
            li.append(Item(item))

    for e in li:
        print e

if __name__ == "__main__":
    main()

Sample output:

link='http://techspot.zzzeek.org/2011/10/29/value-agnostic-types-part-ii', title='Michael Bayer: Value Agnostic Types, Part II'
...

To learn more about reading XMLs with untangle, see my previous post. The call unicode_to_ascii simply converts Unicode to ASCII characters, which is needed if you want to print the result on the terminal.