[Tutor] When to use a Class or just define functions?

Alan Gauld alan.gauld@blueyonder.co.uk
Fri Jun 20 16:20:02 2003


> class Quotes:
>       pass
> 
> Very simple, but what 'extra' benefit does making a class 
> and passing it, really do?  

None whatsoever since 'pass' doesn't pass the class to anywhere 
it tells the interpreter to pass over the line, thus it does 
literally nothing! Classes are only useful if you put some methods
inside them.

One way to illustrate the benefit of classes is to think about 
a word counter for files.

If you put it in a module you might declare a module variable 
to hold the filename. Then you could call the functions to count 
words, sentences etc. Like this:

-----------
import counter

counter.target = open("foo.txt")

words = counter.countWords()
sentences = counter.countSEntences()

print words, ' in ', sentences, 'semtemces'
-------------

Now that works fine but we can only process one file at a time.
Now lets assume we wrote the code as methods of a class which 
had an instance variable holding the file:

-------------
class Counter:
   def __init__(self, fileName): self.target = open(fileName)
   def countWords(self): .....
   def countSentences(self): .....
   def nextSentence(self):....
   def countWordsInSentence(self):....

Now we can create lots of these counter objects, one per file 
and work withthem all at the same time. We couldn't have done 
that with the first version. Of course we could redesign the 
module not to use the global value and pass the file in each 
time, but what if we wanted to step through the files sentence 
by sentence? That gets harder with the module approach, but 
with lots of independant objects its easy! Each object can keep 
track of its current location in the file.

> My main point is when to make a 'new' class or just define 
> a bunch of functions? I could go further and include some 
> of my common functions into the new Quotes class. Not sure 
> what benefit I will get from doing that though?

The above illustrates one occasion. There are others - like 
when you want to pass around chunks of data and have the 
operations available too. Or if you think you might want to
subclass(or extend) the capabilities. eg In the Counter example 
you might want to add the ability to count or move by paragraphs.
You could derive a new subclass and just add two new methods.
All the previous stuff still works but you can extend it.

> I would guess that I could break the functions included in 
> the new class down further and they might be more useful 
> to parts of the program that didn't need the whole 
> previous function. 

Its good practice in designing classes to have the "public" 
methods - ie the ones that people call - implemented in terms 
of "protected" or "private" methods - ones that are only visible 
inside the class. This makes it easy for people subclassing 
your class to change the functions without changing the 
public interface. This technique is known as "hook programming"
because the intrernal functions act like hooks to which you 
can attach new features.

class C:
   def start_f(s)...
   def end_f(s)...
   def f(s):
     s.start_f()
     # do the main thing here
     s.end_f()

Now I can change C's behaviour in a subclass thus:

class D(C):
   def start_f(s):
      C.start_f(s)  # get the otriginal action if needed
      # do some new starting action here


What I've now done is change the pre condsitions around 
the F() method by rewriting the start hook.

Hmmm, That's probably more than you wanted, I got a tad 
carried away there so I'll stop now before I confuse 
everyone, including me!

Alan G
Author of the Learn to Program web tutor
http://www.freenetpages.co.uk/hp/alan.gauld