Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Python (http://www.velocityreviews.com/forums/f43-python.html)
-   -   catching exceptions (http://www.velocityreviews.com/forums/t397415-catching-exceptions.html)

jm.suresh@no.spam.gmail.com 12-16-2006 11:54 AM

catching exceptions
 
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


Amit Khemka 12-16-2006 12:06 PM

Re: catching exceptions
 
On 16 Dec 2006 03:54:52 -0800, jm.suresh@no.spam.gmail.com
<jm.suresh@gmail.com> 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.

Steven D'Aprano 12-16-2006 12:32 PM

Re: catching exceptions
 
On Sat, 16 Dec 2006 03:54:52 -0800, jm.suresh@no.spam.gmail.com 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 12-16-2006 12:34 PM

Re: catching exceptions
 
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.


jm.suresh@no.spam.gmail.com 12-16-2006 01:24 PM

Re: catching exceptions
 

Steven D'Aprano wrote:
> On Sat, 16 Dec 2006 03:54:52 -0800, jm.suresh@no.spam.gmail.com 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.



Steven D'Aprano 12-17-2006 12:16 AM

Re: catching exceptions
 
On Sat, 16 Dec 2006 05:24:28 -0800, jm.suresh@no.spam.gmail.com 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.


Gabriel Genellina 12-17-2006 12:31 AM

Re: catching exceptions
 
On 16 dic, 10:24, "jm.sur...@no.spam.gmail.com" <jm.sur...@gmail.com>
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


Scott David Daniels 12-19-2006 05:16 AM

Re: catching exceptions
 
jm.suresh@no.spam.gmail.com 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.daniels@acm.org


All times are GMT. The time now is 12:18 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.