How to pass a C structure in Python?

Does Python (Programming Language) pass a variable to function by-value or by-reference?

  • I can see Python pass a number or string by value: >>> def foo(x): ...     x += 1 ...     print x ... >>> a 1 >>> foo(a) 2 >>> a 1 If you pass a list to a function, however: >>> def bar(l): ...     l = [1,2,3] ... >>> def bar2(l): ...     l.append(100) ... >>> b = [1,2,3] >>> bar(b) >>> b [1, 2, 3] >>> bar2(b) >>> b [1, 2, 3, 100] It looks to me like in Python, just a "pointer" to the variable is passed to function, not the variable itself. But I am still not sure. Can someone explain to me how variable is passed in Python ?

  • Answer:

    Everything is passed by reference: >>> def id(x): ... return x ... >>> x = 9203409249024 >>> x is 9203409249024 False >>> x is id(x) True Keep in mind that in Python x is y returns true if the two sides evaluate to the same object; that is, it checks pointer equality. This creates a variable x that holds some large integer value (small integers don't work here, because their storage is reused). x is not the same as a new instance of the same integer, but it is the same as itself passed back from a function. You'll see the same behavior with any other type, as far as I'm aware: x is id(x) will always return True. Although everything is passed by reference, you don't normally see that because instances of primitive types like integers, strings, and booleans cannot be modified, so the only way to tell whether they were passed by value or by reference is by using is—and even that won't always work, as Python may reuse the same object if it's immutable anyway. Types like lists and objects, on the other hand, are mutable, so you can directly observe the call-by-reference behavior by doing something like x[0] = 1. It's important to distinguish between a variable and the value it is holding. A function can put a different value inside a variable used as an argument, like this: def foo(x): x = 42 return x and calling foo(y) won't modify the variable y in the calling code, whether it's an integer or a list. However, if y is a list and foo does something like x.append(42), that will modify the list stored in y, since the same underlying object is passed to the function. One confusing point is the += operator. It works both on integers, where x += 1 is basically equivalent to x = x + 1 and therefore simply puts a new value inside the variable (and similarly for strings), and for lists, where x += [1] is equivalent to x.extend([1]): a method call that modifies the list in place. In my mind, this is a minor design flaw in Python.

Jelle Zijlstra at Quora Visit the source

Was this solution helpful to you?

Other answers

There exists confusion due to inconsistent terminology across language communities here. The Pythons language definition does not explicitly state whether it uses call-by-reference or call-by-value (pass-by-reference or pass-by-value) because the important thing is to understand how Python handles variables under the hood. (See the link http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html#other-languages-have-variables provided by Sandeep Shete for a good illustration.) But there is a third party opting for calling what Python does neither of the above, but rather call-by-sharing or call-by-object [1][2][3][4]. Although, there exist very strong opinions regarding this, as you can see from replies to [3]. The main difference is explained very well on the Wikipedia page on http://en.wikipedia.org/wiki/Evaluation_strategy under call-by-sharing: In call-by-sharing an assignments to a function arguments inside the scope of the function is not visible to the caller but because the function has access to the same object as the caller, it can be mutated (given it being a mutable object).  Consequently, if you call a function like so: http://stupidpythonideas.blogspot.jp/2013/11/does-python-pass-by-value-or-by.html def foo(x): x.append(1) x = [2, 3] bar = [0] foo(bar) print(bar) There are three possibilities for what the above example could yield: [0] This would be the result if Python was operating using call-by-value under the hood. A copy of the value [0] would be created and handed to foo. Thus the example above would yield [0] because inside the scope of foo we would be manipulating a copy and bar would not changed by what happens to its copy. [2, 3] Arguably, this is what you would expect in call-by-reference behaviour. Here, rather than receiving a copy the function has access to the object itself through its reference and can manipulate it, even assign it new. Thus the value of bar changes even outside the scope of foo. [0, 1] Finally, this is how Python actually behaves: It does not produce a copy but basically hands a name tag to foo (you can of course argue that this should be called Call-by-reference depending on your understanding). Foo has access to the same object and can mutate it (given the object being mutable). But, at the same time foo cannot make new assignments. The line x.append(1) mutates the existing object. But in the case of the new assignment seen in the example [2, 3] is a new object in its own right, residing at a new address in memory and assigning x = [2, 3] just puts the name tag x on this new object [2, 3] while the old name tag bar is still pointing to the old object. Thus the assignment doesn’t do anything to our old object. So in summation: Python does something akin to call-by-reference because it does pass a form of reference (the name tag) along. But it is different from what you would call true call-by-reference, as seen in languages like Pascal or C++, in so far that it does not allow new assignment but only mutation. This behaviour may look like call-by-value, eg. when the object is immutable. How you want to call this behaviour is up to you. The important thing is not the name but the underlying concepts, I think.  References [1] http://en.wikipedia.org/wiki/Evaluation_strategy [2] http://stupidpythonideas.blogspot.jp/2013/11/does-python-pass-by-value-or-by.html [3] http://www.jeffknupp.com/blog/2012/11/13/is-python-callbyvalue-or-callbyreference-neither/ [4] http://me.veekun.com/blog/2012/05/23/python-faq-passing/

Jessica Verena Schulze

Python has pass-by-value ONLY, just like Java, JavaScript, Ruby, Scheme, Go, Smalltalk, and many other languages. There is no pass-by-reference in Python. Pass-by-value and pass-by-reference are terms dealing with the semantics of variables when passed. They must be defined in a way that is consistent across languages. Here is the definition I use: If a variable is passed to a function, and inside that function, you perform a simple assignment (e.g. = in most languages) to the parameter variable, if it is pass-by-reference, this has the same effect as a simple assignment to the variable in the original scope; if it is pass-by-value, it has no effect on the variable in the original scope. (Note that the definition does not depend on the type of variable or what it represents; it only deals with the semantics of assignment on that variable.) Python has the latter semantics (pass-by-value) always. Basically, the semantics of assignment and passing in Python work exactly identically to the semantics of assignment and passing of reference types in Java. The only types in Java are primitive types and reference types. References are pointers to objects. There are no "object types" in Java, which means you cannot have a value that "is an object", only a value that "points to an object". Java is universally described as pass-by-value only. It works identically in Python -- every value in Python is a pointer to an object. Assignment of one variable to another simply makes both pointers point to the same object; it does not mutate the object that may have been previously pointed to. Ultimately, disagreement on this question is a disagreement on definitions. But whatever definition one uses, it must consistently applied across languages. If you consider Python "pass-by-reference", then you must consider Java "pass-by-reference" too for reference types.

Xuan Luo

I found following two links very useful in understanding some of the core ideas. Short answer: objects are passed as if by reference, not copied. If you change an object in a function, it’ll change in the caller. But! You can’t assign to an argument name and magically have values in the caller change. Long answer: both, and neither. Hmm. This may require some context.[1] [1] http://me.veekun.com/blog/2012/05/23/python-faq-passing/ Also http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html#other-languages-have-variables

Sandeep Shete

Just Added Q & A:

Find solution

For every problem there is a solution! Proved by Solucija.

  • Got an issue and looking for advice?

  • Ask Solucija to search every corner of the Web for help.

  • Get workable solutions and helpful tips in a moment.

Just ask Solucija about an issue you face and immediately get a list of ready solutions, answers and tips from other Internet users. We always provide the most suitable and complete answer to your question at the top, along with a few good alternatives below.