catching exceptions

Discussion in 'Python' started by jm.suresh@no.spam.gmail.com, Dec 16, 2006.

  1. Guest

    Hi, In the following program, I have a class Test which has a property
    x. Its setx function gets a string value and converts it into a float
    and stores into it.

    class Test(object):
    def _getx(self):
    return self._x
    def _setx(self,strvalue):
    try:
    self._x = float(strvalue)
    except ValueError:
    print 'Warning : could not set x attribute to %s' %
    strvalue
    x = property(_getx,_setx)


    def func1(value):
    a = Test()
    try:
    a.x = value
    except ValueError:
    #Pop up a error window.
    print 'This is second catch'


    func1('12')
    func1('12e1')
    func1('a')



    func1('12')
    func1('12e1')
    func1('a')
    >>> func1('a')

    Warning : could not set x attribute to a

    I am looking for a way to call func1's exception handler also.
    Basically I want to have the class's error handler as the basic text
    based one, and in the calling side, If I have gui, I will pop-up a
    window and say the error message.
    One solution is to remove the exception handling inside the class and
    leave the entire thing to the caller (software people call this
    client?) side -- if the caller has access to gui it will use gui or
    else will print the message. Any other way?

    --
    Suresh
     
    , Dec 16, 2006
    #1
    1. Advertising

  2. Amit Khemka Guest

    On 16 Dec 2006 03:54:52 -0800,
    <> wrote:
    > Hi, In the following program, I have a class Test which has a property
    > x. Its setx function gets a string value and converts it into a float
    > and stores into it.
    >
    > class Test(object):
    > def _getx(self):
    > return self._x
    > def _setx(self,strvalue):
    > try:
    > self._x = float(strvalue)
    > except ValueError:
    > print 'Warning : could not set x attribute to %s' %
    > strvalue
    > x = property(_getx,_setx)
    >
    >
    > def func1(value):
    > a = Test()
    > try:
    > a.x = value
    > except ValueError:
    > #Pop up a error window.
    > print 'This is second catch'
    >
    >
    > func1('12')
    > func1('12e1')
    > func1('a')
    >
    >
    >
    > func1('12')
    > func1('12e1')
    > func1('a')
    > >>> func1('a')

    > Warning : could not set x attribute to a
    >
    > I am looking for a way to call func1's exception handler also.
    > Basically I want to have the class's error handler as the basic text
    > based one, and in the calling side, If I have gui, I will pop-up a
    > window and say the error message.
    > One solution is to remove the exception handling inside the class and
    > leave the entire thing to the caller (software people call this
    > client?) side -- if the caller has access to gui it will use gui or
    > else will print the message. Any other way?


    If I gather correctly, i guess in case of errors/exceptions in a class
    function, you want to get the error string. One thing that comes
    straight to my mind is, in such a case use a return statement in
    functions with two arguments.

    for example:
    def foo(self, value):
    try:
    a.x = value
    return True, ''
    except ValueError: return False, 'Float conversion error: %s' %(value)

    and when ever u call the function, check the first return value, It is
    false then alert/print the error message.

    HTH,
    amit.
    --
    ----
    Amit Khemka -- onyomo.com
    Home Page: www.cse.iitd.ernet.in/~csd00377
    Endless the world's turn, endless the sun's Spinning, Endless the quest;
    I turn again, back to my own beginning, And here, find rest.
     
    Amit Khemka, Dec 16, 2006
    #2
    1. Advertising

  3. On Sat, 16 Dec 2006 03:54:52 -0800, wrote:

    > Hi, In the following program, I have a class Test which has a property
    > x. Its setx function gets a string value and converts it into a float
    > and stores into it.


    [snip code]

    Python isn't Java. Are you sure you need properties?


    > I am looking for a way to call func1's exception handler also.
    > Basically I want to have the class's error handler as the basic text
    > based one, and in the calling side, If I have gui, I will pop-up a
    > window and say the error message.
    > One solution is to remove the exception handling inside the class and
    > leave the entire thing to the caller (software people call this
    > client?) side -- if the caller has access to gui it will use gui or
    > else will print the message. Any other way?


    The exception is consumed by the try...except block inside the class,
    so func1 never sees the exception. It might as well not exist.

    Generally, you should keep your class as simple as possible. It shouldn't
    try to manage any exception it can't recover from. In your case, the class
    can't recover from a failure of float(strvalue), so it shouldn't consume
    the exception. Two ways of doing that:

    def _setx(self, strvalue):
    self._x = float(strvalue) # just let the exception propagate

    or

    def _setx(self, strvalue):
    try:
    self._x = float(strvalue)
    except ValueError:
    raise SomeError('could not set x attribute to %s' % strvalue)

    where SomeError should be either ValueError or possibly some custom
    exception (say, MyClassException).

    In either case, the error handling is separate from the object that
    generates the error. And that is as it should be. Now your class can
    remain the same, no matter how the rest of your program handles the
    exception.

    By the way, if you want your class to generate warnings, perhaps you
    should investigate the Warnings module:

    import warnings
    help(warnings)



    --
    Steven.
     
    Steven D'Aprano, Dec 16, 2006
    #3
  4. On Sat, 16 Dec 2006 17:36:00 +0530, Amit Khemka wrote:

    > If I gather correctly, i guess in case of errors/exceptions in a class
    > function, you want to get the error string. One thing that comes
    > straight to my mind is, in such a case use a return statement in
    > functions with two arguments.
    >
    > for example:
    > def foo(self, value):
    > try:
    > a.x = value
    > return True, ''
    > except ValueError: return False, 'Float conversion error: %s' %(value)
    >
    > and when ever u call the function, check the first return value, It is
    > false then alert/print the error message.


    Oh lordy, that is _so_ 1980s programming practice!!!

    I'm not saying that it is never a good idea, but avoiding that sort of
    thing is one of the reasons exceptions were created!


    --
    Steven.
     
    Steven D'Aprano, Dec 16, 2006
    #4
  5. Guest

    Steven D'Aprano wrote:
    > On Sat, 16 Dec 2006 03:54:52 -0800, wrote:
    >
    > > Hi, In the following program, I have a class Test which has a property
    > > x. Its setx function gets a string value and converts it into a float
    > > and stores into it.

    >
    > [snip code]
    >
    > Python isn't Java. Are you sure you need properties?


    I do not know Java. But, object.x = value looks much better than
    object.set_x(value) . Is there any harm in doing it, provided I have to
    do more than just storing the value.

    >
    >
    > > I am looking for a way to call func1's exception handler also.
    > > Basically I want to have the class's error handler as the basic text
    > > based one, and in the calling side, If I have gui, I will pop-up a
    > > window and say the error message.
    > > One solution is to remove the exception handling inside the class and
    > > leave the entire thing to the caller (software people call this
    > > client?) side -- if the caller has access to gui it will use gui or
    > > else will print the message. Any other way?

    >
    > The exception is consumed by the try...except block inside the class,
    > so func1 never sees the exception. It might as well not exist.
    >
    > Generally, you should keep your class as simple as possible. It shouldn't
    > try to manage any exception it can't recover from. In your case, the class
    > can't recover from a failure of float(strvalue), so it shouldn't consume
    > the exception. Two ways of doing that:
    >
    > def _setx(self, strvalue):
    > self._x = float(strvalue) # just let the exception propagate
    >
    > or
    >
    > def _setx(self, strvalue):
    > try:
    > self._x = float(strvalue)
    > except ValueError:
    > raise SomeError('could not set x attribute to %s' % strvalue)
    >
    > where SomeError should be either ValueError or possibly some custom
    > exception (say, MyClassException).
    >
    > In either case, the error handling is separate from the object that
    > generates the error. And that is as it should be. Now your class can
    > remain the same, no matter how the rest of your program handles the
    > exception.
    >
    > By the way, if you want your class to generate warnings, perhaps you
    > should investigate the Warnings module:
    >
    > import warnings
    > help(warnings)

    I will go through it. Thanks a lot.
    >
    >
    >
    > --
    > Steven.
     
    , Dec 16, 2006
    #5
  6. On Sat, 16 Dec 2006 05:24:28 -0800, wrote:

    >> > Hi, In the following program, I have a class Test which has a property
    >> > x. Its setx function gets a string value and converts it into a float
    >> > and stores into it.

    >>
    >> [snip code]
    >>
    >> Python isn't Java. Are you sure you need properties?

    >
    > I do not know Java. But, object.x = value looks much better than
    > object.set_x(value) . Is there any harm in doing it, provided I have to
    > do more than just storing the value.


    Why write set_x in the first place if all it does is set x? Why not just
    have an attribute x and just write obj.x = value? What advantage are you
    gaining?

    One good use of properties is when you need attribute x to be calculated
    on the fly. But there are costs as well: accessing a property is more
    expensive than just accessing an attribute (accessing a property means
    that not only do you access an attribute, but you also run a method). That
    might not matter if your getter and setter are simple enough. Another cost
    is that you have to write the code in the first place, and then you
    have to test it: your class becomes bigger and more complicated. One
    reason why getters and setters are looked at suspiciously is that in the
    Java world, they frequently lead to bloated code. If you gain no benefit
    from that complexity, why pay for it?

    I'm not telling you "don't use properties" -- I'm merely telling you to
    think about why you are using getters and setters in the first place, and
    be sure that you are gaining benefit from them.

    I'm suspicious about your example, because your getter simply looks up a
    private attribute and returns it. Your setter does barely more work: it
    calls float. I'm guessing that your intention is to try to ensure that
    obj.x is only ever a float. But Python isn't designed for that sort of
    strong type checking. It is very, very hard (possibly impossible) to
    ensure calling code can't abuse your classes, and type-checking languages
    only protect against one small set of potential abuse anyway. The usual
    Python philosophy is not to bother, and instead rely on good unit testing
    to test for all bugs, not just type bugs.

    Your class as a tool. All tools can be used or misused. It isn't the
    responsibility of the tool to protect you from misusing the tool (because
    it can't, even if you wanted it to -- the best it can do is protect you
    from some misuses). It is the responsibility of whoever uses the tool to
    not misuse it.

    In practice, what that often (but not always) means is that if you have an
    attribute x that needs to be a float, your class is entitled to assume it
    will always be a float, and the code that uses your class is responsible
    for making sure that it never stuffs a non-float into x. If it does,
    that's a bug in the caller, not in your class, and is best caught by unit
    testing.

    (But does x really need to be a float? Maybe it only needs to be an object
    that acts like a float.)

    That's just something for you to think about.



    --
    Steven.
     
    Steven D'Aprano, Dec 17, 2006
    #6
  7. On 16 dic, 10:24, "" <>
    wrote:
    > > Python isn't Java. Are you sure you need properties?


    > I do not know Java. But, object.x = value looks much better than
    > object.set_x(value) . Is there any harm in doing it, provided I have to
    > do more than just storing the value.


    You've provided the answer: properties are OK if you need to do "more"
    that just store the value. Else, they're a waste of programmer and
    processor time.
    That was not clear on your original post.

    --
    Gabriel Genellina
     
    Gabriel Genellina, Dec 17, 2006
    #7
  8. wrote:
    >
    > class Test(object):
    > ...
    > def _setx(self,strvalue):
    > try:
    > self._x = float(strvalue)
    > except ValueError:
    > print 'Warning : could not set x attribute to %s' % strvalue
    > ...


    I think what you are looking for is:
    class Test(object):
    ...
    def _setx(self, strvalue):
    try:
    self._x = float(strvalue)
    except ValueError:
    print 'Warning : could not set x attribute to %s' % (
    strvalue)
    raise # re-raise the exception that got us here.
    ...

    --Scott David Daniels
     
    Scott David Daniels, Dec 19, 2006
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Marina
    Replies:
    2
    Views:
    478
    Marina
    Jul 8, 2003
  2. Amil Hanish
    Replies:
    0
    Views:
    552
    Amil Hanish
    Apr 13, 2006
  3. Adam Maass
    Replies:
    5
    Views:
    407
    Sudsy
    Jul 22, 2003
  4. Mike Schilling
    Replies:
    2
    Views:
    353
    Mike Schilling
    Jul 16, 2003
  5. Mick
    Replies:
    0
    Views:
    436
Loading...

Share This Page