In Python, why can I multiply a string by a number, but I can't add a string and a number?

7.1k Views Asked by At

In Python, we can do:

'a' * 4

to get 'aaaa'.

We can not do:

'a' + 4

We first have to cast 4 to a string.

Is this just an arbitrary choice to overload * with a definition for a String and Int arg, and to not overload + for a String and Int?

I'm trying to understand how this fits into Python being considered 'Strongly typed', if we define that as the language not performing any implicit type conversions, like how it's not converting 4 to a string in the above example. So in the first example, this is an example of operator overloading, and not an implicit conversion?

In the docs, I can't find a definition of mul or * that takes an Int and a String, only the form that takes 2 Ints. How do we know what overloaded definitions are present?

Reference: https://docs.python.org/2/library/operator.html

1

There are 1 best solutions below

0
On BEST ANSWER

Is this just an arbitrary choice to overload * with a definition for a String and Int arg, and to not overload + for a String and Int?

In essence, yes. However, it's worth noting that the two operations you're talking about are not really parallel. In 'a' * 4, the two pieces are used differently: the string is used as a string, and the number as a number. There is no type conversion going on here. Also note that 'a' * 4 is the same as 4 * 'a', because the types of the two operands make their roles clear, so order doesn't matter.

If (as you seem want) it worked so that 'a' + 4 gave 'a4', that would be a different sort of operation. That would be implicitly making one type act like the other type (here implicitly converting int to string). This can lead to a lot of confusion. For instance, if you do '1' + 2, should you get the number 12 or the string '12'? What about if you do 1 + '2'? Should 1 + '2' behave differently than 1 + 'blah'? If you no longer rely on the object types to make the decision, you have to decide some other way, and none of those other ways is going to be obvious or consistent. You would again have to make an arbitrary choice, something like "always convert to the type of the first argument" or "always convert to string".

Rather than open such a can of worms, Python generally avoids using operator overloading to do implicit type conversion. Where operations can be done on different types, as with string multiplication, the behavior is specifically defined to make use of each type as what it is, not convert it to something else.