The Python interpreter only comprehends pass by object reference. Whether a new object is returned (kind of, but not really, like
pass by value
) or an existing object is modified (kind of, but not really, like
pass by reference
), is entirely dependent on the behavior of the object itself. The Python interpreter follows the same process behind the scenes.
Let's look at a couple of examples. First, let's explore the behavior of
a+=1
where
a
is an immutable object, say something that looks like an integer. Here is the definition of our
immutable
class.
class immutable:
def __init__(self, x):
self.value = x
def __iadd__(self, other):
return immutable(self.value + other)
def __repr__(self):
return f"immutable({self.value})"
And here is an example of its behavior.
>>> a = immutable(1)
>>> b = a
>>> a; b
immutable(1)
immutable(1)
>>> id(a); id(b)
140551985127920
140551985127920
>>> a += 1
>>> a; b
immutable(2)
immutable(1)
>>> id(a); id(b)
140551985326256
140551985127920
>>>
The statement
a+=1
becomes the function call
immutable.__iadd__(a, 1)
. Then
a.value + 1
is used to create a new
immutable
instance. The new object is returned to the Python interpreter and
a
is changed to refer to the new object. (Note that
id(a)
and
id(b)
refer to different objects.)
Here is the definition of our
mutable
class.
class mutable:
def __init__(self, x):
self.value = x
def __iadd__(self, other):
self.value += other
return self
def __repr__(self):
return f"immutable({self.value})"
And here is the same example but using the
mutable
class.
>>> a = mutable(1)
>>> b = a
>>> a; b
immutable(1)
immutable(1)
>>> id(a); id(b)
140551985424320
140551985424320
>>> a+=1
>>> a; b
immutable(2)
immutable(2)
>>> id(a); id(b)
140551985424320
140551985424320
>>>
Just like the previous
immutable
example, the statement
a+=1
becomes the function call
immutable.__iadd__(a, 1)
. Instead of creating a new object, the
value
attribute of
a
is incremented. Now the underlying object has been mutated. The mutated object is returned to the Python interpreter and
a
is changed to refer to the mutated object. (Note that
id(a)
and
id(b)
continue to refer to the same object.)
I've skipped over some of the details. If you want more details, let me know.
casevh