Passing values in Python

89,346

Solution 1

Python passes references-to-objects by value.

Python passes references-to-objects by value (like Java), and everything in Python is an object. This sounds simple, but then you will notice that some data types seem to exhibit pass-by-value characteristics, while others seem to act like pass-by-reference... what's the deal?

It is important to understand mutable and immutable objects. Some objects, like strings, tuples, and numbers, are immutable. Altering them inside a function/method will create a new instance and the original instance outside the function/method is not changed. Other objects, like lists and dictionaries are mutable, which means you can change the object in-place. Therefore, altering an object inside a function/method will also change the original object outside.

Solution 2

Thing is, the whole reference/value concept won't fit into python. Python has no "value" of a variable. Python has only objects and names that refer to objects.

So when you call a function and put a "name" inside the parenthesis, like this:

def func(x): # defines a function that takes an argument
    ... # do something here

func(myname) # calling the function

The actual object that myname is pointing is passed, not the name myname itself. Inside the function another name (x) is given to refer to the same object passed.

You can modify the object inside the function if it is mutable, but you can't change what the outside name is pointing to. Just the same that happens when you do

anothername = myname

Therefore I can answer your question with:

it is "pass by value" but all values are just references to objects.

Solution 3

Answers here have been helpful, but I find the need to exhibit this fine distinction which I haven't seen covered, which I've proven to myself with the subsequent CL experiment:

  1. An immutable object ALONE CANNOT be changed within a function call. (answers so far have said that much...)
  2. BUT, an immutable object CONTAINED WITHIN a mutable object CAN be re-assigned within a method call.

'num' does not change here because it is an immutable Number object [supports my point 1.]:

def incr_num(num):
    num += 1

num = 0

num
0

incr_num(num)

num
0

'list[0]' here is an immutable Number object also.

def incr_list(list):
    list[0] += 1

list = [0]

list[0]
0

incr_list(list)

list[0]
1

So how did 'list[0]', being an immutable Number object, change (supports my point 2.) while the above example's Number object 'num' did not? The immutable Number object 'list[0]' is contained within the mutable list object 'list', while 'num' from the 1st example is just a non-contained Number object (immutable).

Although well-intended, I feel @Stephen Pape top-rated answer (quoted below), and some other similar ones, were not totally correct (and that motivated me to write this answer):

Some objects, like strings, tuples, and numbers, are immutable. Altering them inside a function/method will create a new instance and the original instance outside the function/method is not changed.

My 2nd code experiment above shows a Number object ('list[0]') being altered within a method, and then the original instance outside the function changed.

Solution 4

A reference is passed, but if the parameter is an immutable object, modifying it within the method will create a new instance.

Solution 5

The object is passed. Not a copy, but a reference to the underlying object.

Share:
89,346

Related videos on Youtube

Joan Venge
Author by

Joan Venge

Professional hitman.

Updated on July 05, 2022

Comments

  • Joan Venge
    Joan Venge almost 2 years

    When you pass a collection like list, array to another function in python, does it make a copy of it, or is it just a pointer?

    • Noob Saibot
      Noob Saibot over 10 years
      This question was asked in Feb. '09, while the "original" question was asked in June of that year. Why is this one the duplicate?
    • Makoto
      Makoto over 10 years
      @NoobSaibot: The answers in the "duplicate" are a lot better.
    • akki
      akki about 7 years
      This answer by Mark Ransom and this blog by effbot on Python objects together will make things as clear as they can be.
    • cellepo
      cellepo over 3 years
      @Makoto that does not justify this first question being marked as duplicate. That encourages duplicating Answers.
    • Joan Venge
      Joan Venge over 3 years
      @cellepo: And my comment is deleted too.. Censorship too great job mods!
  • user1066101
    user1066101 over 15 years
    @Harper Shelby: Good, but risky example. Doesn't work for immutable objects like strings, tuples, ints, etc.
  • Federer
    Federer over 14 years
    Very interesting summary :) Thanks.
  • Daniel Pryden
    Daniel Pryden over 12 years
    You first say "Python passes by reference", but then in the quoted text, it says "Python passes references-to-objects by value" -- which is not the same thing! Python is actually not call-by-reference at all, it's call by sharing.
  • Josh Heitzman
    Josh Heitzman over 11 years
    True, but it isn't because the immutable object are being passed by value, but rather because they are automatically copied on mutate.
  • user4815162342
    user4815162342 over 11 years
    Python does not pass by reference, as the term is typically understood (e.g. Pascal or C++). Assigning to the variable does not affect the caller in any way, and this is the case regardless of the data type involved. When calling functions, Python creates a new name for the same object, so that mutating the object is reflected in the caller, but assigning to the function-local variable is not. This is exactly the same mechanism as the one in Java or Lisp. Your answer unfortunately adds to the confusion.
  • deeshank
    deeshank over 10 years
    Good one! :) well explained!
  • sancho.s ReinstateMonicaCellio
    sancho.s ReinstateMonicaCellio almost 9 years
    This is a longer version of the earlier answer stackoverflow.com/a/534389/2707864, worth posting.
  • Tim Richardson
    Tim Richardson over 8 years
    I have decided next time I am asked to explain this, I will use the id() function to show the binding of the name to the reference.
  • Tim Richardson
    Tim Richardson over 8 years
    However, you also need to know when Python creates a new object, and when it dereferences.
  • Elazar
    Elazar over 7 years
    Names are references in the current scope. The only visible difference between "names" and "variables" (as in Java) is when you look at locals(), which most of the time you don't. And yes, Java has several types of primitives whereas Python has only one.
  • vipulnj
    vipulnj almost 7 years
    @user4815162342: just to be clear, assigning to the local variable in the function would create a new object which will be alive during the execution of the function and die when the function is exited. Correct?
  • user4815162342
    user4815162342 almost 7 years
    @vipulnj Correct. Unless, of course, the object is stored in a global variable, in which case it will survive the function's exit - but it will still not affect the object seen by the caller.
  • Tomerikoo
    Tomerikoo almost 4 years
    That last sentence is a perfect summary of what I see many newbies of Python getting very confused with!
  • IqbalHamid
    IqbalHamid almost 3 years
    @cellepo Your answer explains the behaviour but does not explain the reason for this behaviour. I mean what is the difference between a number within a list when passed as an argument; and an integer passed directly as an argument. Why is exactly that one integer changes and another does not?
  • IqbalHamid
    IqbalHamid almost 3 years
    Thank you. Your code provides a brilliant insight. I has tried to amend your solution to articulate it better but the edit queue is full. So I may borrow this to articulate a solution to a similar problem elsewhere. I will link to your answer and provide you due credit.
  • cellepo
    cellepo almost 3 years
    @IqbalHamid why are you not treating me as nicely or respectfuly as your other comment to a different answer here? Why aren't you asking them your questions also? I even provide more explanation than they do, for which you are asking me for more explanation...
  • IqbalHamid
    IqbalHamid almost 3 years
    @celleppo. No disrespect intended. You've presented a fascinating observation. And one that python programmers need to be aware of. So thank you for bringing that to our attention. But my initial reading of your answer left me unclear why this behaviour occurs in python. You went on to highlight a distinction between the 2 scenarios. But I could not understand what it is about a list that makes it mutable. The other person's code said the same as your code but returning references provided extra clarity over what was happening and also how. No disrespect intended. Your ans still helpful
  • cellepo
    cellepo almost 3 years
    I never claimed to explain any reasoning to a level that caters to you personally; the Question did not ask for it. But my free Answer already has indeed had explanation for the reasoning - it is what already existed in bold at the top of my Answer - you can see in edit history that part is unchanged since before your first comment, which shows your lack of due diligence: Read more carefully, and research yourself to find your own answers for your personal preference of needs - at least attempt that, before criticizing my free advice (which already did what you are asking for).
  • cellepo
    cellepo almost 3 years
    If the edit queue is full, then go shorten the queue by reviewing some edits.