Basically, b = a
points b
to wherever a
points, and nothing else.
What you're asking about is mutable types. Numbers, strings, tuples, frozensets, booleans, None
, are immutable. Lists, dictionaries, sets, bytearrays, are mutable.
If I make a mutable type, like a list
:
>>> a = [1, 2] # create an object in memory that points to 1 and 2, and point a at it
>>> b = a # point b to wherever a points
>>> a[0] = 2 # change the object that a points to by pointing its first item at 2
>>> a
[2, 2]
>>> b
[2, 2]
They'll both still point to the same item.
I'll comment on your original code too:
>>>a=5 # '5' is interned, so it already exists, point a at it in memory
>>>b=a # point b to wherever a points
>>>a=6 # '6' already exists in memory, point a at it
>>>print b # b still points at 5 because you never moved it
5
You can always see where something points to in memory by doing id(something)
.
>>> id(5)
77519368
>>> a = 5
>>> id(a)
77519368 # the same as what id(5) showed us, 5 is interned
>>> b = a
>>> id(b)
77519368 # same again
>>> id(6)
77519356
>>> a = 6
>>> id(a)
77519356 # same as what id(6) showed us, 6 is interned
>>> id(b)
77519368 # still pointing at 5.
>>> b
5
You use copy
when you want to make a copy of a structure. However, it still will not make a copy of something that is interned. This includes integers less than 256
, True
, False
, None
, short strings like a
. Basically, you should almost never use it unless you're sure you won't be messed up by interning.
Consider one more example, that shows even with mutable types, pointing one variable at something new still doesn't change the old variable:
>>> a = [1, 2]
>>> b = a
>>> a = a[:1] # copy the list a points to, starting with item 2, and point a at it
>>> b # b still points to the original list
[1, 2]
>>> a
[1]
>>> id(b)
79367984
>>> id(a)
80533904
Slicing a list (whenever you use a :
) makes a copy.