Python does neither. It has names which are bound to values. Values can be either mutable or immutable. This isn't really advanced, so much as unusual, but it is very important to understand when working in Python!
So, in...
answer=42insight=answerinsight=4
...the name answer is bound to the value 42. insight is initially bound to the same value that answer is (names cannot be bound to other names). On the third line, insight is rebound to the value 4.
The behavior you're referring to is actually related to whether the data type being passed is mutable or immutable.
Immutable types seem to behave like pass-by-value because the value cannot be modified.
In that example, foo is passed to increment(), so the parameter num gets bound to the same value as foo. This is identical to num = foo, by the way. However, an integer is immutable, meaning that value cannot be modified. So, num = num + 1 actually rebinds to a new value, 6, which is returned and bound to eggs.
Mutable data types, on the other hand, seem to behave like "pass-by-reference"...
Lists are mutable. Again, when we pass spam to the function, it's the same as if we said numbers = spam; numbers is now bound to the same value as spam. However, because that value is mutable, it can be changed directly, which we do with our numbers.append() call. Because both spam and numbers are still bound to the exact same value in memory, both see the mutation.
Then, when we return numbers, we wind up binding that same value to eggs as well. Thus, spam and eggs are (again) bound to the exact same value in memory.
Python does neither. It has names which are bound to values. Values can be either mutable or immutable. This isn't really advanced, so much as unusual, but it is very important to understand when working in Python!
So, in...
...the name
answer
is bound to the value42
.insight
is initially bound to the same value thatanswer
is (names cannot be bound to other names). On the third line,insight
is rebound to the value4
.The behavior you're referring to is actually related to whether the data type being passed is mutable or immutable.
Immutable types seem to behave like pass-by-value because the value cannot be modified.
In that example,
foo
is passed toincrement()
, so the parameternum
gets bound to the same value asfoo
. This is identical tonum = foo
, by the way. However, an integer is immutable, meaning that value cannot be modified. So,num = num + 1
actually rebinds to a new value,6
, which is returned and bound toeggs
.Mutable data types, on the other hand, seem to behave like "pass-by-reference"...
Lists are mutable. Again, when we pass
spam
to the function, it's the same as if we saidnumbers = spam
;numbers
is now bound to the same value asspam
. However, because that value is mutable, it can be changed directly, which we do with ournumbers.append()
call. Because bothspam
andnumbers
are still bound to the exact same value in memory, both see the mutation.Then, when we return
numbers
, we wind up binding that same value toeggs
as well. Thus,spam
andeggs
are (again) bound to the exact same value in memory.Common immutable data types:
bool
:True
,False
str
(string):"Hello, world!"
int
,float
,complex
tuple
:(1, 2, 3)
bytes
frozenset
Common mutable data types:
list
:[1, 2, 3]
set
:{1, 2, 3}
dict
(dictionary):{1: 'a', 2: 'b', 3: 'c'}
Dead Simple Python: Data Typing and Immutability
Jason C. McDonald ・ Jan 17 '19 ・ 19 min read
Also watch Ned Batchelder's excellent talk on this topic.
WOW. Well explained. Thanks, Jason