views:

55

answers:

2

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?
+2  A: 
class MyRecord:
    #....  
    def __getitem__(self, key):
        return getattr(self, key)
Ned Batchelder
Thanks! I added a try-except to turn `AttributeError`s into `KeyError`s.
wds
+2  A: 

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)
FogleBird
Very neat that. Unfortunately I can't really avoid some derived attributes here and there (I could add them all to the object, but that seems like double work and just mucks up the namespace).
wds
Derived attributes are exactly what properties are good for, but I can't tell from your question how many you would need or if they're all just len or what.
FogleBird
There's some output formatting here and there (collapsing lists to comma-separated values and the like), which wouldn't make sense to duplicate. Not if it can be avoided anyway. +1 though, it's the best answer to the question if there aren't a couple of detail problems like that.
wds