tags:

views:

124

answers:

6

I am still struggling with understanding classes, I am not certain but I have an idea that this function I have created is probably a good candidate for a class. The function takes a list of dictionaries, identifies the keys and writes out a csv file.

First Q, is this function a good candidate for a class (I write out a lot of csv files

Second Q If the answer to 1 is yes, how do I do it

Third Q how do I use the instances of the class (did I say that right)

import csv
def writeCSV(dictList,outfile):
    maxLine=dictList[0]
    for item in dictList:
        if len(item)>len(maxLine):
            maxLine=item
    dictList.insert(0,dict( (key,key) for key in maxLine.keys()))

    csv_file=open(outfile,'ab')
    writer = csv.DictWriter(csv_file,fieldnames=[key for key in maxLine.keys()],restval='notScanned',dialect='excel')
    for dataLine in dictList:
        writer.writerow(dataLine)
    csv_file.close()
    return
+2  A: 

The main idea behind objects is that an object is data plus methods. Whenever you are thinking about making something an object, you must ask yourself what will be the object's data, and what operations (methods) will you want to perform on that data.

Functions, more readily translate to methods than classes.

So, for instance, if your dictList is data upon which you often call writeCSV, then perhaps make a dictList object with method writeCSV:

class DictList(object):
    def __init__(self,data):
        self.data=data
    def writeCSV(self,outfile):
        maxLine=self.data[0]
        for item in self.data:
            if len(item)>len(maxLine):
                maxLine=item
        self.data.insert(0,dict( (key,key) for key in maxLine.keys()))
        csv_file=open(outfile,'ab')
        writer = csv.DictWriter(
            csv_file,fieldnames=[key for key in maxLine.keys()],
            restval='notScanned',dialect='excel')
        for dataLine in self.data:
            writer.writerow(dataLine)
        csv_file.close()

Then you could instantiate a DictList object:

dl=DictList([{},{},...])
dl.writeCSV(outfile)

Doing this might make sense if you have more methods that could operate on the same DictList.data. Otherwise, you'd probably be better off sticking with the original function.

unutbu
+1  A: 

If you want to write a lot of CSV files with the same dictList (is that what you're saying...?), turning the function into a class would let you perform initialization just once, and then write repeatedly from the same initialized instance. E.g., with other minor opts:

class CsvWriter(object):

  def __init__(self, dictList):
    self.maxline = max(dictList, key=len)
    self.dictList = [dict((k,k) for k in self.maxline)]
    self.dictList.extend(dictList)

  def doWrite(self, outfile):
    csv_file=open(outfile,'ab')
    writer = csv.DictWriter(csv_file,
                            fieldnames=self.maxLine.keys(),
                            restval='notScanned',
                            dialect='excel')
    for dataLine in self.dictList:
        writer.writerow(dataLine)
    csv_file.close()

This seems a dubious use case, but if it does match your desire, then you'd instantiate and use this class as follows...:

cw = CsvWriter(dataList)
for ou in many_outfiles:
  cw.doWrite(ou)
Alex Martelli
A: 

I don't think your writeCSV is in need of a class, typicaly class would be used when you have to update some state(data) and then act on it, may be with various options.
e.g. if you need to pass around your object, so that other function/method can add values to it or your final action/output function has many options or you think same data can be processed, acted upon in many ways.

Typically practical case would be if you have multiple functions which act on same data or a singe function whose optional parameter list is going to long, you may think of converting it into a class.

If in your case you had various options and need to insert data in increments, you should make it a class.

Usually class name would be noun, so function(verb) writeCSV -> class(noun) CSVWriter

class CSVWriter(object):
    def __init__(self, init-params...):
        self.data = {}

    def addData(self, data):
        self.data.update(data)

    def dumpCSV(self, filePath):
        ...

    def dumpJSON(self, filePath):
        ....
Anurag Uniyal
+1  A: 

When thinking about making objects, remember this:

  1. Classes have attributes - things that describe different instances of the class differently

  2. Classes have methods - things that the objects do (often involving using their attributes)

Objects and classes are wonderful, but the first thing to keep in mind is that they are not always necessary, or even desirable.

That said, in answer to your first question, this doesn't seem like a particularly good candidate for a class. The only thing different between the different CVS files you're writing are the data and the file you write to, and the only thing you do with them (ie, the only method you would have) is the function you've already written).

Even though the first answer is no, it's still instructive to see how a class is built.

class CSVWriter:
    # this function is called when you create an instance of the class
    # it sets up the initial attributes of the instance
    def __init__(self, dictList, outFile):
        self.dictList = dictList
        self.outFile = outFile

    def writeCSV(self):
        # basically exactly what you have above, except you can use the instance's
        # own variables (ie, self.dictList and self.outFile) instead of the local
        # variables

For your final question - the first step to using an instance of a class (an individual object, if you will) is to create that instance:

myCSV = CSVWriter(dictList, outFile)

When the object is created, init is called with the arguments you gave it - that allows your object to have its own data. Now you can access any of the attributes or methods that your myCSV object has with the '.' operator:

myCSV.writeCSV()
print "Wrote a file to", myCSV.outFile

One way to think about objects versus functions is that objects are generally nouns (eg, I created a CSVWriter), while functions are verbs (eg, you wrote a the function that writes CSV files). If you're just doing something over and over again, without re-using any of the same data, a function by itself is fine. But, if you have lots of related data, and part of it gets changed in the course of the action, classes may be a good idea.

Daniel G
A: 

I think question 1 is pretty crucial as it goes to the heart of what a class is.

Yes, you can put this function in a class. A class is a set of functions (called methods) and data together in one logical unit. As other posters noted, probably overkill to have a class with one method.

Sam Post
+2  A: 

For this you need to understand little bit concepts of classes first and then follow the next step. I too faced a same problem and followed this LINK , I m sure u will also start working on classes from your structured programming.

Shantanu Gupta