[Tutor] exceptions problem
Steven D'Aprano
steve at pearwood.info
Mon Sep 13 13:59:03 CEST 2010
On Mon, 13 Sep 2010 08:55:46 pm Francesco Loffredo wrote:
> I don't like this rough behaviour of int(), spitting out an
> exception if given a legitimate string representation of a float. Can
> some of you Tutors explain me why it must be so?
The int() function behaves as a constructor, producing an integer object
from its argument. It has two jobs:
(1) truncate (round-to-zero) numbers to a whole number by dropping any
fraction part without rounding; and
(2) convert strings to an integer.
So int() can truncate all of these numbers:
>>> from decimal import Decimal
>>> from fractions import Fraction
>>> int(3) # an int is already an int, so no change
3
>>> int(5.6)
5
>>> int(Decimal("-1.2"))
-1
>>> int(Fraction(12, 5))
2
But not this one, because it's not clear what the integer part of a
complex number is:
>>> int(5.23 + 11.76j)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can't convert complex to int
Okay, that's numbers out of the way. Pretty straightforward.
When it comes to strings, we're doing *conversions*, not truncation, so
we need to decide what are the rules for converting strings. The usual
rule is that, apart from a possible leading + or - sign, we expect a
string of digits. Nobody expects int("two hundred and thirty-seven") to
return 237. What digits are allowed? That depends on the base -- Python
supports bases from 2 to 36:
>>> int("123") # base 10 is the default
123
>>> int("123ff", 16) # hexadecimal
74751
>>> int("123ff", 36)
1777371
There's also a "base 0", which uses the string's prefix to specify the
base:
>>> int("0x123ff", 0) # 0x... means a hex number
74751
So what are we to make of a string like "1.95"? Obviously it's not an
integer, and "." is not a valid digit. If you, the programmer, are
reading in data from a file and are expecting *integers*, and somebody
slipped in a decimal-point, that is just as troublesome as if they
slipped in a semi-colon or the letter Z. Should "1.95" be truncated to
1, or rounded to 2? Should it remain a float? Should the dot be
interpreted as a digit in some unusual base?
Python refuses to guess what int("1.95") should mean, and it raises an
error, just as it does for int("1+1") or int("two").
--
Steven D'Aprano
More information about the Tutor
mailing list