1

If I've defined a class that takes in two or more parameters:

class SomeObject:
    def __init__(self, int_param, str_param):
        #if parameters are wrong type:
            raise TypeError("wrong type") 
...

if (__name__ == "__main__"):
    try:
        invalid_obj = SomeObject('two', 'string')
        print (invalid_obj)
    except TypeError as e:
        print (e)

it'll print "wrong type", but is there a way for it to also return which argument is raising the exception? Can I get the output to be:

"wrong type 'two'"

? I've tried print (e.args), print (repr(e)), and simply print(e) but the invalid argument never gets printed. Just wondering if this is possible, thank you.

edit: It works with a custom exception type, and if I list each parameter being tested individually - I also have ValueError catching for both the int_param and str_param as well, so I wanted to see if I can condense the if statements to just:

#if params not right type: 
    raise TypeError
#if params contain invalid value:
    raise ValueError

and still get it to return the specific invalid argument that's causing the error. I'll definitely keep the custom Exception type in mind for future assignments; unfortunately for this one the instructor has "raise TypeError" and "raise ValueError" as requirements for full marks. She doesn't require the invalid argument to be returned though, that was just me being curious if I could manage it. I ended up with:

#if int_param not int:
    raise TypeError("int_param {0} given is invalid type".format(int_param))
#if str_param not int:
    raise TypeError("str_param {0} given is invalid type".format(str_param))
#if int_param is an invalid value:
    raise ValueError("int_param {0} given is invalid value".format(int_param))
....

and so on. If anyone can see a cleaner way to do this (without a custom Exception type), please let me know!

Melissa
  • 55
  • 5
  • you could make your own error https://docs.python.org/2/tutorial/errors.html#user-defined-exceptions – R Nar Oct 30 '15 at 20:30
  • 1
    If you are checking the parameters one at a time, it should be easy to raise an Error with help text indicating that from within the `__init__` function. – BlackVegetable Oct 30 '15 at 20:30

3 Answers3

3

You can make your own exception:

class SomeObjectException(TypeError):
    def __init__(self, msg, which):
        TypeError.__init__(self, msg)
        self.which = which

Then:

class SomeObject:
    def __init__(self, int_param, str_param):
        #if parameters are wrong type:
            raise SomeObjectException("wrong type", int_param) 

And:

if (__name__ == "__main__"):
    try:
        invalid_obj = SomeObject('two', 'string')
        print (invalid_obj)
    except SomeObjectException as e:
        print (e, e.which)

Also see proper way to declare custom exceptions in modern Python.

Community
  • 1
  • 1
Claudiu
  • 224,032
  • 165
  • 485
  • 680
  • Won't you have to still branch on which parameter causes the Exception? As it is, you'll still have two different `SomeObjectException`s being raised in the code. – BlackVegetable Oct 30 '15 at 20:35
  • @BlackVegetable: Yeah. In one case you do `raise SomeObjectException("wrong type", int_param)`; in the other you do `raise SomeObjectException("wrong type", str_param)`. But these will both be caught by the one `except SomeObjectException as e` line. – Claudiu Oct 30 '15 at 20:36
  • Ah, of course. I'm sorry, my brain didn't follow that exception logic until the end. :) +1 – BlackVegetable Oct 30 '15 at 20:36
  • does this mean I would need to have an if statement for each parameter; `#if int_param is not int: raise SomeObjectException("wrong type", int_param) #if str_param is not str: raise SomeObjectException("wrong type", str_param)` ? – Melissa Oct 30 '15 at 23:40
  • @Melissa: Yeah, wherever the check fails, when it fails, you raise the exception there. – Claudiu Oct 31 '15 at 00:27
2
class SomeObject:
    def __init__(self, int_param, str_param):
        if type(int_param) != int:
            raise TypeError("int_param: wrong type") 
        if type(str_param) != str:
            raise TypeError("str_param: wrong type")
John Gordon
  • 29,573
  • 7
  • 33
  • 58
  • thanks, I figured if I listed each type of error I wanted to catch I could probably do it, but the code I have also catches a few ValueError types as well, so I wanted to condense all the possible TypeError and ValueError scenarios into one if statement for each error type... I guess if I want to print the argument causing the error I would need to separate each scenario? – Melissa Oct 30 '15 at 23:44
0

Maybe you should look for the traceback module.

instead of raise TypeError("wrong type") wrap traceback.print_exc() in try, except and see if that's what you looking for.

Leustad
  • 375
  • 1
  • 5
  • 20