You're not overwriting anything.
1) You'll construct a new string, this will most definitely not be in the same location as the old string because that still exists.
2) The name (variable) is then made to point at the new value instead of the old one.
3) Python will notice that there aren't any references to the old string any more, and can now remove it from memory. This happens automatically and may not happen at once. This is called garbage collection.
If you create a string of length 1 million one character at a time, creating a new string each time, then you will have copied a total of 500000*1000000 characters. (One million strings are created, and on average it will be half a million characters long)
That said, there's a hack in CPython (that's the standard implementation) where it actually changes the string instead of re-creating it, if it sees that the reference count for that string indicates that there are no other references to it so that it won't break anything by changing it anyway, it's just faster. But your code is saying to do it in a very slow way, it's better to write it the way it's supposed to happen. And if you run your code in another Python version, you won't get this hack, which again, you shouldn't rely on even if it was always there.