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 vallist
This can be adapted to writing XML, or JSON or whatever you need
No comments:
Post a Comment