[Tutor] "Overloading" methods
Steven D'Aprano
steve at pearwood.info
Fri Sep 17 03:00:38 CEST 2010
On Thu, 16 Sep 2010 10:02:18 pm Michael Powe wrote:
> Hello,
>
> Strictly speaking, this isn't overloading a method in the way we do
> it in Java. But similar. Maybe.
Ha ha, you sound like me -- I can recognise design patterns, but I have
no idea what they're called, or why anyone bothers to distinguish
between the "builder" pattern and the "factory" pattern... the
difference is too subtle for me.
It sounds like what you're trying to do is a design pattern, or
combination of patterns.
> I am writing a module for processing web server log files and one of
> the methods I provide is to extract a given query parameter and its
> value.
So you have a module that provides a single log-processing class with a
single method that extracts query parameters?
If there will only ever be a single instance of the class, you should
consider making the methods ordinary functions. Instead of:
inst = module.LogProcessor()
inst.extract(stuff)
you get:
module.extract(stuff)
Modules give you Singleton behaviour for free!
> Because there are several types of log files with different
> line structures, I had the thought to write methods with descriptive
> names that simply returned a generic method that processed the method
> arguments. e.g.,
>
> def setpattern_iis(self,pattern,parameter) :
> type='iis'
> return pattern_generator(self,type,pattern,parameter)
>
> In this case, creating a regular expression to parse the log lines
> for a query parameter.
Sounds fine to me. I would question the name -- a method
called "setpattern_iis" should, well, *set* a pattern somewhere (a
global? a property?), not return a value. But other than that, the
basic tactic is sound. Whether it is more or less straightforward
compared to alternatives is another question. (See below.)
> This is just a bit more "self documenting" than using the generic
> method with the 'type' argument and requiring the user to enter the
> type.
True, but consider how the caller might use this. I'm guessing what your
API might be:
import module
log_parser = module.Log_Parser() # make a generic parser
regex = logParser.setpattern_iis(pattern, parameter) # get a regex
results = logParser.search_log(regex, log) # and use it
Am I close?
Perhaps a better API might be:
import module
log_parser = module.IIS_Log_Parser() # make a IIS parser
results = log_parser.search_log(pattern, parameters, log)
In this case, the basic strategy would be to have an abstract log
parser:
class AbstractLogParser(object):
type = None
def __init__(self):
if self is AbstractLogParser:
raise TypeError('abstract class cannot be initialised')
# define common methods
def pattern_generator(self, pattern, parameter):
type = self.type
return type + "spam" # whatever...
def search_log(self, pattern, parameters, log):
regex = self.pattern_generator(pattern, parameter)
return regex.search(log) # whatever
Creating a new subclass is easy:
class IISLogParser(AbstractLogParser):
type = 'iis'
--
Steven D'Aprano
More information about the Tutor
mailing list