[Tutor] help with refactoring needed -- which approach is morePythonic?

Brian van den Broek bvande at po-box.mcgill.ca
Thu Feb 10 10:43:02 CET 2005

Alan Gauld said unto the world upon 2005-02-10 02:58:
>>The main change in refactoring is moving it to OOP. I have a method
>>that serves as the entry point for parsing the files.
> Not an object? If you are thinking terms of what the methods
> do its probably not OOP...

Hi Alan,

That may well be :-) What I've done is have a class
File_in_the_format, and have all the parsing work going on in methods
of the class. My class is called with a filepath, the __init__ method
calls the _master_parser method which breaks things into head and
body, calling appropriate methods and so on.

I was thinking it was OOP even with just the one class as I am making
use of encapsulation and the class namespace to avoid passing
parameters about.

> I would expect to see an object for the File, another for the Header,
> a third for the Body and another for the Node. The first (containing
> a header and bosdy object) is responsible for cracking open the file
> and reading the lines, recognising where it has a header and sending
> those lines to the header object and the rest to the bosy object.
> The body object then reades those lines and creates a Node object
> per node feeding it lines as appropriate...

I originally tried to see how to do it that way, but got stuck. I'll
point to where by using your pseudo code below.


> Pseudo code:
>        class Body:
>           def __init__(self,content):
>             self.contents = contents
>             self.nodes = []
>           def parse(self):
>              for line in self.contents:
>                  if line == NodeStartTag:
>                     node = Node()        # Stuck here -- BvdB
>                  if line == NodeEndTag:
>                     self.nodes.append(node)
>                  node.append(line)
>           def __del__(self): del self.nodes

I got stuck at the place where I added a comment above. I didn't see
how I could do that, since I didn't yet have all of the node lines in
hand when it would be time to build a node.

>        class Node:
>          def __init__(self,lines=[]):
>               self.lines = lines
>          def append(self,item):        # Bing! -- BvdB
>               self.lines.append(item)
>          def parse(self):
>               # your parsing method here.

Well, that flipped a switch! I *knew in the abstract* that I can
define interfaces [?] like .append and .__add__. The puzzle pieces
just hadn't come together yet. They aren't all there yet either, but a
half an hour in the interpreter has already cleared away much
puzzlement over how to pull this off. So, thanks a lot for the push!

> Whats the advantage? If you have different node types you
> can easily subclass Node and not change the File or Body
> classes, just write a slightl'y different line parser.
> That way your code remains more stable - you never need
> to change working code to add a new node type...

Well, I don't *think* these considerations are going to enter into my
particular task. I'm working with a well documented text format for a
shareware app I have where the developer has recently changed the file
format to an undocumented binary format. So, I can be fairly confident
that my particular target is one I have complete knowledge about.

But, I absolutely see the point for the general case. I'm off to scrap
the code that made me happy :-( and redo it this way to learn better
habits :-)

Thanks again,

Brian vdB

More information about the Tutor mailing list