#1
  1. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Location
    France
    Posts
    154
    Rep Power
    142

    Question Question about pass by value to functions


    Hi,


    I have a question about passing mode of actual parameters to functions in python (I'm using python 3.6).
    There is something that I think I don't understand properly reading the online documentation.

    https://docs.python.org/3/tutorial/c...ning-functions
    ...
    The actual parameters (arguments) to a function call are introduced in the local symbol table of the
    called function when it is called; thus, arguments are passed using call by value (where the value
    is always an object reference, not the value of the object).
    ...
    My question is: If as it is said above, the passed value is always an object reference, then like C programming language are we talking
    about the address of the variable (= pointers)? Because if the answer is yes, I don't understand why the function doesn't change
    the original variable. I mean I think I don't really get the correct meaning of what is an Object reference in Python. Is it an address?
    exactly like a pointer in C programming language or the pointed value?


    Thanks in advance,
    Regards,
    Dariyoosh
  2. #2
  3. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    May 2009
    Posts
    653
    Rep Power
    39
    The answer is yes it does pass by reference. If you print the id() before the function call and as the first line within the function, you will see that they are indeed at the same location. You can only change the original variable (location) if it is mutable https://codehabitude.com/2013/12/24/...-vs-immutable/ If you want to keep the change, it has to be returned from the function. Note that any variable created under a function is local to that function and is garbage collected when the function exits.
    Code:
    ## strings are not mutable - doesn't matter if it is in a function or not 
    a_str="abc",  a_str
    print id(a_str)
    a_str += "def"
    print id(a_str), a_str
    
    def change_it(a_list):
        a_list.append("def")
        b_list=["c"]  ## garbage collected
    
    a_list=["a", "b", "c"]  ## lists are mutable
    print id(a_list), a_list
    change_it(a_list)
    print id(a_list), a_list  ## same memory location, different contents

    Comments on this post

    • dariyoosh agrees
    Last edited by dwblas; March 30th, 2017 at 11:54 PM.
  4. #3
  5. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Location
    France
    Posts
    154
    Rep Power
    142
    Very nice explanation & thanks for the link. Indeed I hadn't taken into account that an "int" object
    is immutable. Thanks to the link you provided, I read the following:

    ...
    Not all python objects handle changes the same way. Some objects are mutable,
    meaning they can be altered. Others are immutable; they cannot be changed but
    rather return new objects when attempting to update.
    ...
    To verify I did the following test based on your example:

    python Code:
     
    x = 10
     
     
    def myfun(x):
        print('before assignment in myfun id(x) = ' + str(id(x)))
        x = x * 2
        print('After  assignment in myfun id(x) = ' + str(id(x)))
     
     
    print('Before calling myfun       id(x) = ' + str(id(x)))
    myfun(x)
    print('After  calling myfun       id(x) = ' + str(id(x)))


    And here is the output:

    Code:
    Before calling myfun       id(x) = 140496623183168
    before assignment in myfun id(x) = 140496623183168
    After  assignment in myfun id(x) = 140496623183488
    After  calling myfun       id(x) = 140496623183168
    At the third line in the above mentioned output there is a new address. So if I
    undrestand correctly, I tried to update an immutable object inside a function, therefore
    a new object (so with a new reference) was created which is local to the function and
    at the end of the function block will be garbage-collected. Am I right?
    Regards,
    Dariyoosh
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    May 2009
    Posts
    653
    Rep Power
    39
    which is local to the function and
    at the end of the function block will be garbage-collected
    Correct, so you return it if you want to keep it
    Code:
    x = 10
     
    def myfun(x):
        print('before assignment in myfun id(x) = ' + str(id(x)))
        x = x * 2
        print('After  assignment in myfun id(x) = ' + str(id(x)))
        return x 
     
    print('Before calling myfun       id(x) = %d  %s' % (id(x), x))
    x = myfun(x)
    print('After  calling myfun       id(x) = %d  %s' % (id(x), x))
  8. #5
  9. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Location
    France
    Posts
    154
    Rep Power
    142
    Thanks for the confirmation.
    Regards,
    Dariyoosh
  10. #6
  11. Contributing User
    Devshed God 1st Plane (5500 - 5999 posts)

    Join Date
    Aug 2011
    Posts
    5,888
    Rep Power
    509
    If you pass a mutable object it is the content of that object that retains the change.
    https://docs.python.org/3/glossary.html see argument entry
    Code:
    class C:
        pass
    
    def f(o):
        o.an_attribute = 'changed'
        # a_list[item] = new value
        # etc.
    
    v = C()
    print('an_attribute' in dir(v), '# expect False')
    
    f(v)
    print('an_attribute' in dir(v), '# expect True')
    
    
    
    
    def g(o):
        o = C()
        o.whatever = 'this is a new object'
    
    w = C()
    print('whatever' in dir(v), '# expect False')
    
    g(w)
    print('whatever' in dir(v), '# expect False')

    Comments on this post

    • dariyoosh agrees
    [code]Code tags[/code] are essential for python code and Makefiles!

IMN logo majestic logo threadwatch logo seochat tools logo