[Tutor] constructors

dman dman@dman.ddts.net
Thu, 11 Apr 2002 14:14:24 -0500


On Thu, Apr 11, 2002 at 07:42:54AM -0400, Erik Price wrote:
| 
| On Thursday, April 11, 2002, at 12:23  AM, Karthik Gurumurthy wrote:
| 
| >>So, if I had an class with a method that did a database access, then 
| >>the
| >>constructor could do something like initialize the variables used in 
| >>the
| >>class, and create a database connection.  If the database connection
| >>fails, then the constructor could return false, which would fail the
| >>creation of the object instance, so that we don't waste our time
| >>accessing the methods of the class since we already know we couldn't
| >>establish a database connection.
| >
| >>...does this sound right?
| >
| >Yes Perfect!. you have picked up a nice example.
| >Normally constructors do not have a return value. Instead they throw
| >exceptions.
| >
| >So if you have a DatabaseManager class which control access to the 
| >database,
| >you w'd probabyl try
| >initializing the connections in the constructor. If it fails, you w'd
| >probably signal the same by throwing
| >an exception. So the client w'd'nt be able to use that object.
| 
| I see.  The use of constructors is becoming much more concrete to me.  
| Thank you Karthik.  But as always, this conversation now brings up yet 
| another question! :)  It's a simple one though.  I'm just wondering 
| whether it would be better to throw an exception from within the class 
| method (or constructor), or whether it would be better to simply do an 
| "if" test and have it return false -- and then throw an exception from 
| the calling script itself, if the "new object" calling fails.  I would 
| have leaned toward the former -- returning false from a failed method, 
| and then throwing up an error message from the calling script because 
| the creation of a new object instance failed, but that's because I'm not 
| totally clear on exceptions yet (they don't have them in PHP AFAIK, I 
| just write my own error-handling code).

Usually it is better to throw an exception.  In either case, you can't
return a value from __init__ -> the object already exists and is
referenced by 'self', the __init__ just initializes the data in it.
If the __init__ method completes, then the client gets the reference
to the object.  You can return 'false' or 'self' or 'fubar', but the
client will never see it.  Ex :

class False :
    def __init__( self ) :
        return 0

class Except :
    def __init__( self ) :
        raise "init failed"

print False()
print Except()


In addition, with exceptions you don't need to constantly check
functions for sentinal return values.  I once posted an example C
snippet (from a real project I did for school) and then rewrote it
using python syntax and exceptions to show how much shorter and
clearer the code became.  This was probably 2 years ago, and I don't
remember which list it was.  Google isn't helping either.

With exceptions, you raise one where there is an error, and you can be
descriptive about it.  The client code doesn't need to deal with any
errors, if it doesn't want to, and the exception propagates up the
call stack until either it is handled or the program exits with an
error.  Thus you can have stuff like :

def do_something() :
    # this function may fail, but we can't do anything about it here
    do()

try :
    print "1"
    do_something()
    print "2"
    do_somethingelse()
except Foo :
    print "foo!"


The do_something function doesn't need to do anything special (like
check a return value and propagate it by returning it) to not ignore
error conditions.  The module-level code doesn't need to interrupt the
flow of the code by checking a return value either, and can handle the
same type of error from both functions identically (if it wants to).

HTH,
-D

-- 

For society, it's probably a good thing that engineers value function
over appearance.  For example, you wouldn't want engineers to build
nuclear power plants that only _look_ like they would keep all the
radiation inside.
    (Scott Adams - The Dilbert principle)