How Best to Coerce Python Objects to Integers?
Steve D'Aprano
steve+python at pearwood.info
Tue Jan 3 19:26:08 EST 2017
On Wed, 4 Jan 2017 10:09 am, Ethan Furman wrote:
> And, of course, whether or not "except Exception" is too broad depends on
> the use-case.
I'm having trouble thinking of *any* use-case where this would be useful.
His intention, it seems, is to write a function which simply cannot fail,
presumably so that he can write code which consumes the output and just
keeps going no matter what he throws at it:
graph = make_graph()
incoming_data = [1, 12, 7, "hello", None, [], {}, 5]
for obj in incoming_data:
graph.draw_point(int_or_else(obj))
But of course that's impossible:
class Evil:
def __int__(self):
os.abort()
Or for that matter:
class Evil:
def __int__(self):
time.sleep(2147483647)
So his code still can fail under some circumstances. And so it should. Why
is my input data including such evil objects? I should find out why. I'm
having trouble seeing how it could be anything but a programming bug.
He gives the rationale for this function:
A scenario that’s more realistic than the Unintable class might
be a class that wraps an industrial sensor. Calling int() on an
instance normally returns a value representing pressure or
temperature. However, it might reasonably raise a
SensorNotReadyError.
Okay. Let's suppose it can return either an integer as a string, some
arbitrary non-numeric string to indicate a sensor error, or raises
SensorNotReadyError. Then this would be an appropriate function to use:
def int_or_else(value):
try:
return int(value)
except ValueError:
assert isinstance(value, str)
# consider logging the error?
return None
except SensorNotReadyError:
return None
Now when he connects up to the sensor and starts reading values, it will
work, but if his input gets contaminated with arbitrary junk objects (a
sign of a programming bug in his code) he will find out about it.
One possible use-case might be something like Excel, where there are two
data types: numbers, and text, and numeric operations on text will just
skip them altogether. If you were to build an object-oriented spreadsheet,
where the cells can contain any object not just numbers and text, then you
could potentially have a situation like:
Column A
Row 1: 1
Row 2: ftp_server()
Row 3: 2
Row 4: 3
Row 5: =sum(A1:A4)
and you (arguably) want the result to be 6 rather than some error. Or do
you? I can make a good case for skipping text cells, as Excel does, but I'm
not sure that ftp_server should be skipped. So I'll count that as a
use-case, but a dubious one.
Another possible use-case might be the REPL for an interpreter, where you
want the REPL to keep going no matter what exceptions take place. But I
don't think this is the right way to do that, and it's not how the Python
REPL works either.
Other than that, I'm not seeing any use-case where this sort of thing is
anything but a bad idea.
--
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.
More information about the Python-list
mailing list