[From nobody Mon Aug 10 08:57:13 2009
Return-Path: &lt;p.lussier@comcast.net&gt;
X-Original-To: python-talk-bounces@dlslug.org
Delivered-To: python-talk-bounces@borlaug.bfccomputing.com
X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6
Received: from QMTA08.westchester.pa.mail.comcast.net
	(qmta08.westchester.pa.mail.comcast.net [76.96.62.80]) by
	borlaug.bfccomputing.com (Postfix) with ESMTP id 46BE7D16EB for
	&lt;python-talk-bounces@dlslug.org&gt;; Mon, 10 Aug 2009 08:11:54 -0400 (EDT)
Received: from OMTA05.westchester.pa.mail.comcast.net ([76.96.62.43]) by
	QMTA08.westchester.pa.mail.comcast.net with comcast id
	Sb1K1c0040vyq2s58cBk7T; Mon, 10 Aug 2009 12:11:44 +0000
Received: from taz.paulntooz.homelinux.org ([76.24.128.93]) by
	OMTA05.westchester.pa.mail.comcast.net with comcast id
	ScBj1c00C212PJc3RcBjVG; Mon, 10 Aug 2009 12:11:44 +0000
Received: from taz.comcast.net (localhost [127.0.0.1]) by
	taz.paulntooz.homelinux.org (Postfix) with ESMTP id 3977F9AE18F; Mon, 10
	Aug 2009 08:11:40 -0400 (EDT)
From: Paul Lussier &lt;p.lussier@comcast.net&gt;
To: python-talk-bounces@dlslug.org
Subject: OOP, when and when not to use it...
Date: Mon, 10 Aug 2009 08:11:39 -0400
Message-ID: &lt;871vnjna10.fsf@comcast.net&gt;
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1.50 (gnu/linux)
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
X-bfccomputing-MailScanner-Information: Please contact the ISP for more
	information
X-bfccomputing-MailScanner-ID: 46BE7D16EB.C10F2
X-bfccomputing-MailScanner: Found to be clean
X-bfccomputing-MailScanner-SpamCheck: not spam, SpamAssassin (not cached,
	score=1.009, required 5, BOTNET_SERVERWORDS -1.00, J_CHICKENPOX_12 0.60,
	J_CHICKENPOX_31 0.60, J_CHICKENPOX_34 0.60, J_CHICKENPOX_39 0.60,
	KHOP_HELO_FCRDNS 0.60, RCVD_IN_JMF_YE 0.01, SPF_NOT_LIKELY_SPAM -1.00, 
	SPF_PASS -0.00)
X-bfccomputing-MailScanner-SpamScore: s
X-MailScanner-From: p.lussier@comcast.net
Content-Transfer-Encoding: 7bit


Hi folks,

I've been lurking on this list for quite a while and just finished
reading through the thread where Bruce feels a bit lost in when/how to
use OOP methodologies vs. a more traditional style.  I'd like to offer
my thoughts from the perspective of a novice programmer with a decent,
though basic understanding of the OOP way.  My own introduction to OOP
came from perl, which I've been writing in for over 15 years.  I've only
been playing with python for a little over 6-8 months now, but I've
found that there's little difference between the two languages when it
comes to how you organize and use the code you write (obviously the
syntax and the code it self differs greatly, as &quot;the perl way&quot; and &quot;the
python way&quot; are very, very different mindsets).

First, OOP is really nothing more than a different way to organize your
code.  There's nothing magical about it.  An &quot;object&quot; is just a &quot;thingy&quot;
that does &quot;stuff&quot; and has &quot;things&quot;.  Which is a more technical way of
saying that &quot;Objects have methods and attributes&quot;.  The methods are the
means of an object &quot;doing stuff&quot; and the attributes are the means of an
object &quot;having stuff&quot; or characteristics.  A car can move forwards,
backwards, turn in circles; it has 2 or 4 doors, 4 or more wheels, etc.

Objects come in different &quot;types&quot; which simply means that certain
methods and attributes are slightly different than the defaults.  For
example, a truck is a type of car that might only have 2 doors, but 6
wheels and a cargo area.  Seeing this type of thing usually implies that
very vague and confusing topic of &quot;inheritance&quot;, which simply means
you've &quot;extended a class&quot;.  I.e. you had one type of object that does
and has certain properties, and you've created a new type of object that
still has the basic properties of the original (i.e. it's inherited from
the &quot;parent class&quot;) but it extends that basic idea to do and have more
stuff.

When do you use OOP vs. a more traditional style?  Well, whenever it's
more useful to think of what you're doing in the terms of objects.  And
there isn't any reason you have to write entirely in an OOP fashion.
You can use some libraries which provide classes and others which don't.

I find that when I need to maintain state, it's usually a good idea to
start using objects.  When are you &quot;maintaining state&quot;, whenever you
start needing to pass a lot of variables into functions, or trying to
figure out the current values of variables as the pertain to a specific
&quot;thingy&quot;, you're maintaining state.  And passing lots of variables gets
to be both tedious and error-prone.

Another way to look at OOP is that you want to keep all the data
pertaining to specific things together.  I always find that once my API
for a function hits 3 or more parameters, maybe I'd better start
thinking about objects instead.  If I mutter to myself something like,
&quot;I should push all this stuff onto an array, and simply pass the array
into this function to simplify things.&quot;, that's usually my clue I need
objects.

I think that does it for what are objects, and when to use them.  So,
what about methods and attributes?  Methods are nothing more than
functions.  Plain and simple.  The only difference between a &quot;method&quot;
and a &quot;function&quot; is that a &quot;method&quot; has direct access to any given
object's state without that state being explicitly passed into the
method.  For example, say I wanted to add to numbers, I can do this in
the traditional way:

    def add(a, b):
        return a + b

&gt;From outside the library, you would access this function like so:

  import foo

  answer = foo.add(4,3)

Or, maybe I have an object where one attribute is a base value with a
new number being added to it:

    def add(self, b):
        if not self.baseValue:
           return b
        return self.baseValue + b

&gt;From outside the library, you would access this method like so:

     import foo

     bar = foo.foo()
     answer = bar.add(4)

In the first example, I need to pass in both values.  In the second,
I'mm assuming there's an existing value to which I'm adding and I have
access to it through &quot;introspection&quot;, i.e. I can access anything within
a class using 'self'.

Also, with respect to the second example, I could write it so that
rather than simply returning the value, I stored it in the object as an
attribute of that object somewhere:

    def add(self, b):
        if not self.baseValue:
           self.baseValue = b
        else: 
           self.baseValue += b
        return self.baseValue

And I could use this like so:

     import foo

     bar = foo.foo()
     bar.add(4)
     print bar.baseValue

Does this make sense ?  If this needs more explanation or I need to
expand upon anything here, feel free to ask.  Also, asking these types
of questions on the main GNHLUG list might be useful as well, since
there are several very experienced programmers there who can provide
lots of insight into different methodologies and practices.

I don't know of any decent books which provide a basic understanding of
OOP. One decent document, though perl-oriented is the perltoot man page
( perldoc perltoot, or man perltoot) which is a pretty decent
intro-level explanation of OOP.

--
Paul
]
