what to do when instance of class fails to initialize ?

Peter Otten __peter__ at web.de
Wed Aug 20 04:53:08 EDT 2003


Tom Van den Brandt wrote:

> If I have an __init__ for a class and the initialisation can't go through
> (example: missing or wrong arguments), how do I return an error to the
> caller (from main() function)?  When I do a return statement in the
> __init__ it says __init__ should return None...  I can stop the flow with
> raise 'BlahBlah'. But then the program exits.

Missing arguments raise an exception, for wrong arguments you can use
assertions:
def __init__(self, color):
    assert color in ["red", "green", "blue"], "Unknown color"

These errors should all be ironed out during the design/debugging phase.
It's a good idea to fix them as soon as possible, so for small apps it would
be OK to terminate the program immediately. For larger apps, where you do
not want programming errors in less important parts or currently
unavailable resources to terminate the whole app, you can do somethng like
this

CONDITION = False
WENT_WRONG = None

#Make up your own Exception
class ConstructionFailed(Exception): pass

class Test:
    def __init__(self, data, condition):
        if not condition:
            raise ConstructionFailed
        self.data = data
    def useIt(self):
        print "using", self.data

#You can now catch it in your client code:
try:
    test = Test("bla", CONDITION) # how would you access a result from
__init__() here?
except ConstructionFailed:
    test = None

if test is not WENT_WRONG:
    test.useIt()

However, I don't like exceptions from inside __init__():
The constructor would typically fail if some resources cannot be acquired
and you would then end up writing destruction/release code in the
constructor.

class Test2:
    def __init__(self, data):
        self.data = data
    def useIt(self):
        print "using", self.data

def makeTest2(data, condition):
    if condition:
        return Test2(data)
    else:
        return None

test2 = makeTest2("bla2", CONDITION)
if test2 is not WENT_WRONG:
    test2.useIt()

For newstyle classes I think you can also modify the __new__() method
to return the WENT_WRONG value, but I haven't done that yet.

Peter




More information about the Python-list mailing list