A CSV writer decorator for functions returning a list (row)
I was looking for a clean way to implement a repeatable pattern where I could have a function return a value list and for this value list to be output to a CSV. The hope is that it should be adaptable to any other target format as well.
After a bit of research I came across:
And the decorator mentioned in it seemed like an excellent idea.
The additional requirement for this was to render the header (or field names) for the csv as a one time output for the top line of the CSV file.
The following assumptions are made:
- The 'out' file handle is a global and is setup prior to calling the function
- The 'attrNameList' is a global and is the header that should be the first line of the CSV file.
- The function passed to the decorator returns a compatible list-type value such that decorator can render it using the csv.writer.
I am guessing this is not quite rigorously pythonic due to the expectations from the passed-function - whereas a true decorator might expect to be completely agnostic of the function it decorates. But I think it is still reasonable and reasonable is good enough for me in many cases.
For the header, a single boolean flag is injected into the function to indicate whether to write the header or not.
So here is the decorator code:
def writeCSV(func): def wrapcsv(*args,**kwargs): global out global attrNameList cw=csv.writer(out, delimiter=",",lineterminator='\n') if wrapcsv.header==False: cw.writerow(attrNameList) wrapcsv.header=True funcval= func(*args,**kwargs) cw.writerow(funcval) return funcval wrapcsv.header=False return wrapcsv
And here is a function it could decorate (I was parsing an LDIF file and extracting specified attributes to a CSV file):
@writeCSV def reportAttrs(dn,ent): global attrNameList global out vallist=[] for attrName in attrNameList: if ent.has_key(attrName.lower()): vallist.append(ent[attrName.lower()][0]) else: vallist.append("") if attrName.lower() == "dn": vallist.append(dn) return vallistThis can be adapted to writing XML, or JSON or whatever you need
No comments:
Post a Comment