Page 1 of 1 [ 5 posts ] 

UnLoser
Veteran
Veteran

User avatar

Joined: 28 Mar 2012
Gender: Male
Posts: 655

20 Oct 2012, 5:06 pm

In Python, the assignment operation does different things depending on the context. I'm sure any experienced Python programmer knows this, but:

If the expression on the right of the = sign is just a variable, then the variable on the left is assigned by reference to whatever is on the right of "=".

However, if the expression on the right of the = sign is not simply a variable(for example, the expression x + 1), then one of two things can happen. If the variable to be assigned to(which is on the left of "=") points to an immutable object, such as an int or a string, then the variable is assigned by reference to a newly created object, and the object it previously pointed to is left unchanged. If the variable to be assigned to points to a mutable object, however, then the variable is assigned by value, that is, the object it points to is modified.

Did I get all that right? I'll probably get criticized for this, but I think this is very, very bad language design. Intuitively, one would expect "=" to do the same thing all the time, and I'm sure it's been a major stumbling block for all sorts of newbies(myself included). Add in the fact that the official docs are not very clear about this(they do kind of hint at it, but they don't describe the behavior in detail), and you've got huge potential for confusion.

I would prefer there to be 2 distinct assignment operations. "=" would modify the value of the object, unless the object is immutable, in which case it would throw an exception. "IS" would simply point the reference variable to a new object, creating a new object as necessary.

I like the way Java does it. Primitives are assigned by value, objects are assigned by reference(although Python has no concept of primitives, so...).



Ancalagon
Veteran
Veteran

User avatar

Joined: 25 Dec 2007
Age: 45
Gender: Male
Posts: 2,302

21 Oct 2012, 10:55 am

UnLoser wrote:
Did I get all that right?

From looking at "Python in a Nutshell", it doesn't look like you did (although I'm not a Python expert). According to that book, assignment just rebinds a variable.

It sounds like you ran into some specific problem, but I can't tell exactly what it was from the description.

Quote:
I like the way Java does it. Primitives are assigned by value, objects are assigned by reference(although Python has no concept of primitives, so...).

Java primitives are essentially immutable. You can't change a primitive value. I can't really see a difference between how the languages handle immutability (other than terminology difference and which things are considered immutable).


_________________
"A dead thing can go with the stream, but only a living thing can go against it." --G. K. Chesterton


UnLoser
Veteran
Veteran

User avatar

Joined: 28 Mar 2012
Gender: Male
Posts: 655

21 Oct 2012, 5:31 pm

From looking at "Python in a Nutshell", it doesn't look like you did (although I'm not a Python expert). According to that book, assignment just rebinds a variable.

For immutable objects like ints, yes. But if you have a mutable like a list, assignment will change the value of the object itself, unless the expression on the right of "=" is just simply a variable. You can prove this with the following bit of code:

a = [1,2]
b = a
a = [5,6]
print(b)
(this will print [5,6])

Now integers, being immutable, don't show the same behavior. When you try to assign a new value to a, it will create a new object and bind a to it, leaving the original object(that b is still bound to) unchanged.

It sounds like you ran into some specific problem, but I can't tell exactly what it was from the description.


No, I'm not having any difficulties right now. This particular quirk has given me a lot of trouble in the past, though.

Java primitives are essentially immutable. You can't change a primitive value. I can't really see a difference between how the languages handle immutability (other than terminology difference and which things are considered immutable)

Well, Java primitives may be immutable under the hood, but they behave as if they're always assigned directly by value, even if Java is technically changing references.



2fefd8
Tufted Titmouse
Tufted Titmouse

User avatar

Joined: 25 Jul 2012
Age: 36
Gender: Male
Posts: 44

21 Oct 2012, 6:17 pm

UnLoser wrote:
...if you have a mutable like a list, assignment will change the value of the object itself, unless the expression on the right of "=" is just simply a variable. You can prove this with the following bit of code:

a = [1,2]
b = a
a = [5,6]
print(b)
(this will print [5,6])...


No, actually it won't (try it). I'm pretty sure this "issue" is due to your misunderstanding of the language.

On the other hand, if you replaced a = [5, 6] with a.append(99) then this would change b (as expected since they refer to the same object). You may find the id function to be useful for investigating which objects are the same and which are not.



UnLoser
Veteran
Veteran

User avatar

Joined: 28 Mar 2012
Gender: Male
Posts: 655

21 Oct 2012, 6:51 pm

Ah, I think you're right. If you actually assign to the list itself, it will only change what the variable references. I was mistaking it for the case where you only change a particular element of the list.

That was a pretty big error. My bad :oops:

But thanks for clearing up my confusion.