MiMA
MiMA

Reputation: 41

error exception handling in python

this is my code:

class personData ():
    def __init__(self, age, spouse = None, children = 0):
        self.age = age
        self.children = children
        self.spouse = spouse
        if self.spouse == None:
            del self.spouse
            print "A %s year old person" % str(self.age)    


    def marries(self, name):
        if self.spouse == None:
            self.spouse = name
        else:
            try:
                self.marries(name)
            except Exception as detail:
                print "spouse exists:", self.spouse

    def divorces(self):
       if self.spouse == None:
            raise AttributeError,  " Not married, divorce impossible"

what I trying to do is:

def divorces(self):
 if self.spouse != None:    ##   thats mean the person has a spouse,
   self.spouse = None       ##    I think that should remove the spouse, right?

Here should come exception if we call divorce again, because the spouse is removed.

Let's say my:

person = personData(30, 'Sue')

person.spouse would be Sue, if I call person.marries('Anna') an exception is raised, now if I call person.divorce() it will remove the spouse ('Sue'). what I'm stuck at is when I call person.divorce() it should raise exception saying that "no spouse exist" and I'm unable to do that, any help would be appreciated.

Upvotes: 3

Views: 106

Answers (2)

Martin Tournoij
Martin Tournoij

Reputation: 27852

def divorces(self):
    if hasattr(self, 'spouse'):
        self.spouse = None

This will always return True, the spouse attribute may be set to None, but it's still set. So the else branch where the error is printed will never be reached.

so, you'll need to change it to something like:

    if self.spouse == None:
        raise Exception('Not married')

In your __init__ function you're doing:

    if self.spouse == None:
        del self.spouse

I would just skip this, and set self.spouse to None; This way there's no need for getattr().

Example

Since you seem to be somewhat confused about the full solution, here's the entire class:

class personData ():
    def __init__(self, age, spouse = None, children = 0):
        self.age = age
        self.children = children
        self.spouse = spouse

    def marries(self, name):
        # There is already a spouse, we don't do polygamy
        if self.spouse != None:
            raise AttributeError("Already married")

        # There is no spouse, so we can marry. You may kiss and a all that.
        self.spouse = name

    def divorces(self):
        # There is no spouse, so we can't divorce
        if self.spouse == None:
            raise AttributeError("Not married, divorce impossible")

        # We diverse, and reset the spouse
        self.spouse = None


person = personData(30, 'Sue')
person.divorces()
person.marries('Anna')
person.divorces()

# This gives an error
person.divorces()

Bonus tip

In the marries() function, you're doing:

try:
    marries(self,name)
except Exception as detail:
    print "spouse exists:", self.spouse

this is incorrect. What this does, is call the function marries() (which doesn't exist) with the class instance self and name as parameters.

What you want to do instead, is:

self.marries(name)

This calls the function marries() on the class instance self. The self parameter is automagicly added by Python, you never need to add this yourself for a simple function call.

This error went unnoticed because you're catching all exceptions. These "Gotta catch 'em all" kind of pokemon exceptions are almost always a bad idea, because you're catching not just the error you expected, but also all the errors the didn't expect, such as programming errors.

(I'm also confused as to why you're using recursion here?)

Upvotes: 2

mgkrebbs
mgkrebbs

Reputation: 865

You are not directly raising an exception, which is what is appropriate if raising an exception is the desired result. (Alternatively, you could just print a message and not deal with any exceptions.) You have no need to use try - except here. Instead, just raise the exception, like:

if self.spouse == None:
    raise Exception( 'Divorce called but no spouse' )

Also, you'll never reach your current try section because hasattr(self, 'spouse') is always true. Another thing is that your marriage exception is happening because of an infinite recursive call of marries, not because of directly raising an exception. You should not be calling marries from inside of marries.

Upvotes: 2

Related Questions