Ahh, so it's a mutable thing. That makes sense that I can't change a
mutable object and thus can't affect it outside of the function. Does
that mean Python functions aren't always byref, but are sometimes
byval for nonmutables?
Reverse: boolean constants are immutable and can not be changed,
you can only move the name used to access on to some other object.
If you want to try relating to Visual Basics "byref" "byval",
then they are neither. They are closer to a "copy reference"; changes to
the /reference copy/ do not propagate back out... Changes to the item
the reference, uh, references, do propagate out.
And it doesn't matter what they are referencing... If it is an
object that lets you "go inside to make changes" it is a mutable object,
and operations that "go inside" make no changes to the "reference"
itself.
def sample(l1, l2, l3):
l1.append(4)
l2 = [l2, 4]
l3[1] = 4
a = [1, 2]
b = [3, 4]
c = [5, 6]
sample(a, b, c)
The first line is NOT changing the l1 reference, it is going
inside l1 and changing the insides. "l1" and "a" BOTH reference a list
object that started with [1, 2]. The append opened that object, and
jammed the 4 into it... "a" and "l1" still reference the same list
object, but the list object now has [1, 2, 4]
The second line, OTOH, is changing the l2 reference; it is
creating a new list containing a reference to the object that l2 is
attached to and a reference to a constant 4, THEN it is saying the l2
NOW references the new list -- but since the name l2 only exists inside
the function, it doesn't affect the outside world... "l2" and "b"
initially reference the list object [3, 4]. The assignment first creates
a new list (with no references) of [reference to [3, 4], 4], then "l2"
is changed from a reference to [3, 4] to be a reference to [reference to
[3, 4], 4]; "b" is still a reference to [3, 4]
The third one, again, is opening the referenced object. "c" and
"l3" are references to a list containing [5, 6], "l3[1]" opens the list
and makes the second element 4. "l3" and "c" still reference the same
list.
Now, in that last, it may look like we are changing an immutable
integer. We are not. In all those lists where I have a simple integer:
[5, 6]
the actual list contents are:
[reference to 5, reference to 6]
so that third line is not changing the 6 to a 4, it changing the
"reference to 6" into a "reference to 4"
Names in Python are always (not just in function parameters)
references to objects. An assignment to a name itself always changes the
reference from the old object to a new object. Assignments to qualified
names (l3[1], l1.append(), etc.) are changing the references INSIDE the
object the name references (as long as that object is a mutable object),
but do not change the reference of the name.
--