catching exceptions

J

jm.suresh

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')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?
 
A

Amit Khemka

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')
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.
--
 
S

Steven D'Aprano

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)
 
S

Steven D'Aprano

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!
 
J

jm.suresh

Steven said:
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.
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.
 
S

Steven D'Aprano

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.
 
G

Gabriel Genellina

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.
 
S

Scott David Daniels

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
(e-mail address removed)
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top