Python Forum
Pass by object reference when does it behave like pass by value or reference? - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: Pass by object reference when does it behave like pass by value or reference? (/thread-29512.html)



Pass by object reference when does it behave like pass by value or reference? - mczarnek - Sep-06-2020

I've read a lot and sort of get it, though it hasn't clicked yet.. could you explain pass by object reference like this:
In what situations does Python's pass by object reference behave like pass by value vs pass by reference? In what situations is it different?

Thanks!


RE: Pass by object reference when does it behave like pass by value or reference? - casevh - Sep-07-2020

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


RE: Pass by object reference when does it behave like pass by value or reference? - perfringo - Sep-07-2020

I suggest to read and/or watch Ned Batchelder Pycon 2015 presentation Python Names and Values


Quote:Call by value or call by reference? People also get tangled up trying to explain whether Python uses call by value, or call by reference. The answer is: neither. This is a false dichotomy, again because people are trying to mis-apply concepts from one language onto all languages.