Question

First some background. I'm parsing a simple file format, and wish to re-use the results in python code later, so I made a very simple class hierarchy and wrote the parser to construct objects from the original records in the text files I'm working from.

At the same time I'd like to load the data into a legacy database, the loader files for which take a simple tab-separated format. The most straightforward way would be to just do something like:

print "{0}\t{1}\t....".format(record.id, record.attr1, len(record.attr1), ...)

Because there are so many columns to print out though, I thought I'd use the Template class to make it a bit easier to see what's what, i.e.:

templ = Template("$id\t$attr1\t$attr1_len\t...")

And I figured I could just use the record in place of the map used by a substitute call, with some additional keywords for derived values:

print templ.substitute(record, attr1_len=len(record.attr1), ...)

Unfortunately this fails, complaining that the record instance does not have an attribute __getitem__.

So my question is twofold:

  • do I need to implement __getitem__ and if so how?
  • is there a more elegant way for something like this where you just need to output a bunch of attributes you already know the name for?
Was it helpful?

Solution

class MyRecord:
    #....  
    def __getitem__(self, key):
        return getattr(self, key)

OTHER TIPS

If you make attr1's length a property or attribute of the record class (so you're really just printing instance attributes as the title implies), you could just do this.

attrs = ['id', 'attr1', 'attr1_len', ...]
print '\t'.join(getattr(record, attr) for attr in attrs)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top