Richard Prosser wrote:
It seems to me that the essential problem is that of assignment in general, which (I believe) creates a reference on the LHS to the object on the RHS,
I would like to understand the reasoning behind such design decisions but I can't find any 'deep' explanations at present
So if you or anyone else can explain exactly why such odditties are implemented I would be grateful.
Python's assignment semantics are only an "oddity" to people whose prior exposure to programming languages is very limited. To anyone familiar with almost any other dynamic language -- such as Lisp, Scheme, Smalltalk, or Javascript -- it's not only unsurprising, it's the *obvious* thing to do. So I wouldn't class it as a "gotcha" in the same sense as truly Python-specific features like default argument evaluation and list comprehension variable scope.
As for rationale, it comes down to something like this: Copying large chunks of data is expensive, so it makes sense to do it only when you really need to. And experience shows that most of the time you *don't* need to copy things.
Furthermore, copying some kinds of things automatically and not others (as some other languages such as VB and Java do) makes the rules needlessly complicated and difficult to remember.
So Python does the simplest possible thing and doesn't copy anything by default. If you want a copy, you need to do something explicit to make it happen.
Unfortunately it is almost certainly too late to propose fixes (if appropriate) for such quirks in Python 3
Python's assignment behaviour is most definitely *not* something that needs "fixing"!