a = 4.0 print a.is_integer() True 'ha' * a TypeError: can't multiply sequence by non-int of type 'float' unichr(a) TypeError: integer argument expected, got float
One thing that really annoys me in Python is duck typing. Not the idea, mind you, but the way it is implemented by the library: the fact that something walk and quacks like a duck does not mean that you can use it instead of a duck. Exhibit one: I have a variable that claims it is an integer, but I cannot use it as an integer.
The core problem is that the system used in Python for numbers is a total mess. See the
is_integer() method I used above? it is only implemented by the type
float, so the only way for a callee to check if some number is actually an integer is to call a method that is not defined on integers. Even for numerical types where the return value of
is_integer() could actually change, like the new
Fraction type introduced in Python 2.6 does not define it. This was supposed to be usable as drop-in replacement for floats.
def foo(x): return x % 10 * 4 + x % 15 * 2
The other problem is that Python overload operators in smart ways, this, coupled with duck-typing results in completely non-intuitive behaviour. The function on the side can return the string
'aaaaff'. Still one, would hope that overloading and duck-typing would ensure that the caller would never need to worry about calling the right function because of the type of his data. Wrong. How many Python programmers know that they should use
math.fsum instead of
sum when adding up float numbers?
sum(['h', 'e', 'l', 'o'], '') TypeError: sum() can't sum strings [use ''.join(seq) instead] a = [,,] sum(a, ) [1, 2, 3]
Someone might argue that doing type-checks and dispatch control to the optimal back-end would be prohibitively expensive, so Python cannot do that. But it does, but only to be pedantic about it.