Unification of Methods and Functions

David MacQuigg dmq at gain.com
Fri May 7 21:08:09 EDT 2004


On Fri, 07 May 2004 15:59:20 +1200, Greg Ewing
<greg at cosc.canterbury.ac.nz> wrote:

>David MacQuigg wrote:
>> Static methods
>> are necessary because it is a very natural thing to write a method in
>> a class that needs to work without being bound to any particular
>> instance.
>
>I beg to differ. It might seem natural to someone who's
>been exposed to C++ or Java, but I don't think it's
>a priori a natural thing at all.

I'm not fond of C++ or Java.  Python is my first actual use of OOP.

>In Python, a function defined inside a class is a method.
>If you want a function to be a method, you put it inside
>a class. If you don't want it to be a method, you don't
>put it inside a class. It's as simple as that.

I really don't care if we call something a method or a function.  What
I care about is that a program is well-structured and easy to
understand.  I seem to be getting a lot of heat for putting the show()
functions in multiple classes in my Animals_2.py example.  The
alternatives proposed seem to make the structure less clear.  

Instead of having each part of the total show() functionality in its
appropriate class [1] I'm told that I need to put all of this at the
global level.  One suggestion was to find some regularity in all the
show functions and write a global function to generate all outputs
based on that regularity.  This won't work, because in general, there
is no such regularity.

Another possibility I have thought about is having a global function
that selects among four blocks, depending on the type of the instance
that called the show() function.  If its a Cat, we need all four
output blocks. If its a Mammal, we need just Mammal and Animal.  In
other words, replicate the inheritance behavior of classes with some
kind of if ... elif ... elif ... elif ... structure.  This will be a
pain to write, compared to the elegance of just having each show()
function call its parent.

The real problem with these alternatives, however, is that it puts
stuff that belongs in a particular class, outside of that class.  This
will make the code harder to understand, and harder to maintain.  When
I need to add a Feline class between Mammal and Cat, I must remember
to edit the global show() function, adding stuff unique to Feline, and
changing the logic of the selections to include the new block.  With a
large hierarchy of classes this is going to be a mess, certainly more
mess than just adding a few 'staticmethod' lines to the existing
classes.

Maybe I'm missing an option here.  I don't claim to be an expert in
Python.

-- Dave

[Note 1]  A function belongs in a class if the variables it works with
are unique to that class.  If it works with variables from several
classes, it belongs in the class of a common ancestor.  For optimum
modularity and encapsulation, we should put each function as low as
possible in the hierarchy of classes, without excessive duplication.
The tradeoff is you want to avoid crowding all your functions at the
top, and avoid unnecessary replication of the same functionality in
multiple classes at the bottom.

Example:  If I had a function that needed only Cat variables, except
for one variable from Parrot, I would not put that function in the
Animal class.  The better tradeoff is to leave it a Cat function, and
reach out with a fully-qualified reference to grab that one Parrot
variable. ( I might also put a ### flag on the line in Cat where that
outside variable is needed, so I don't later forget about this
external dependency.)




More information about the Python-list mailing list