Python study notes series 012: pass-by-value or pass-by-reference?

Guide:

1. Variables and Objects

2. Mutable and Immutable Objects

3. References

 

In C/C++, pass-by-value and pass-by-reference are two ways of passing function parameters. Due to the mentality, Python beginners who are transferred from C/C++ often wonder: In Python, is function parameter passing by value or by reference?
Look at the following two pieces of code:

def foo(arg):
arg = 5
 print (arg)
x = 1 
foo(x) #output 5 
print (x) #output 1

def foo(arg):
arg.append(3)
x = [1, 2 ]
 print (x) # prints [1, 2] 
foo(x)
 print (x) # prints [1, 2, 3]

After reading the first piece of code, some people say that this is pass-by-value, because the function does not change the value of x; after reading the second piece of code, some people say that this is pass-by-reference, because the function changes the content of x.
So, are functions in Python pass-by-value or pass-by-reference?

1. Variables and Objects

We need to know that "variables" in Python are different from "variables" in C/C++.
In C/C++, when you initialize a variable, you declare a block of storage and write the value. Equivalent to putting a value into a box:
int a = 1;

Now there is an integer 1 in the "a" box, which will replace the contents of the box a when another value is assigned to the variable a:
a = 2;

When you assign a variable a to another variable, the value in the a box is copied and put into a new "box":
int b = a;

In Python, a variable can be said to be a "label" or "reference" to an object in memory:
a = 1

Now the variable a points to an int object in memory (a is equivalent to the label of the object). If you reassign a, the label a will move and point to another object:
a = 2

The original int object with the value 1 still exists, but we can no longer access it through the a identifier (when an object does not have any label or reference to it, it will be automatically freed). If we assign the variable a to another variable, we just add a "label" to the current object in memory:
b = a

To sum up, in Python, a variable is just a label and an identifier, which points to an object in memory. Therefore, variables do not have types, and types belong to objects, which is why variables in Python can be assigned to any type.


In python, values ​​are passed by reference.
We can use id() to determine whether two variables are references to the same value. We can understand the id value as the address of that piece of memory.

>>> a = 1
>>> b = a
>>> id(a) 
13033816
>>> id(b) #Note that the id values ​​of the two variables are the same
13033816
>>> a = 2
>>> id(a) #Note that the id value of a has changed
13033792
>>> id(b) # The id value of b remains the same
13033816

>>> a = [1, 2]
>>> b = a
>>> id(a)
139935018544808
>>> id(b)
139935018544808
>>> a.append(3)
>>> a
[1, 2, 3]
>>> id(a)
139935018544808
>>> id(b) #Note that a and b always point to the same address 
139935018544808
View Code

 

2. Mutable and Immutable Objects

In Python's basic data types, we know that numbers, strings, and tuples are immutable objects, while list, dict, and set are modifiable objects. So what is the difference between mutable and immutable? See the example below:

a = 1 # a points to an int object in memory 
a = 2 # reassign

When reassigning a, because the original value of 1 cannot be changed, a will point to a new int object with a value of 2. (as shown above)

lst = [1, 2] # lst points to an object of type list in memory 
lst[0] = 2 # reassign the first element in lst

Because the list type can be changed, the first element is changed to 2. More precisely, the first element of lst is of type int, and a new int object is assigned to the first element during reassignment, but for lst, the list-type object it refers to has not changed, only the list The content (one of the elements) changed.
Well, here we can easily explain the first two pieces of code:

def foo(arg):
arg = 5
 print (arg)
x = 1 
foo(x) #output 5 
print (x) #output 1

The above code passes x as an argument to the function, and both x and arg point to an object with a value of 1 in memory. Then in the function when arg = 5, since the int object is immutable, create a new int object (value 5) and let arg point to it. And x still points to the original int object with the value 1, so the function does not change the x variable.

def foo(arg):
arg.append(3)
x = [1, 2 ]
 print (x) # prints [1, 2] 
foo(x)
 print (x) # prints [1, 2, 3]

This code also passes x to the function foo, so both x and arg point to the same object of type list. Because the list object can be changed, the function uses append to add an element at the end, and the content of the list object has changed, but x and arg still point to this list object, so the content of the variable x has changed.

3. References

Is there any difference when variables of mutable and immutable types are used as function parameters respectively?
Does Python have pointer parameter transfer similar to C language?

>>> def selfAdd(a):
... """自增"""
... a += a
...
>>> a_int = 1
>>> a_int
1
>>> selfAdd(a_int)
>>> a_int
1
>>> a_list = [1, 2]
>>> a_list
[1, 2]
>>> selfAdd(a_list)
>>> a_list
[1, 2, 1, 2]

Function parameters in Python are passed by reference (note that it is not passed by value). For immutable types, the dependent variable cannot be modified, so the operation does not affect the variable itself; for variable types, the operation in the function body may change the incoming parameter variable.

think about why

>>> def selfAdd(a):
... """ Increment """ 
... a = a + a #We changed this sentence of the function body 
...
 >>> a_int = 1
>>> a_int
1
>>> selfAdd(a_int)
>>> a_int
1
>>> a_list = [1, 2]
>>> a_list
[1, 2]
>>> selfAdd(a_list)
>>> a_list
[ 1, 2] #Think about why it hasn't changed?

Summary:
x += x is to modify the space pointed to by x directly, instead of letting b point to a new one.
x = x+x first calculate the result on the right side of the = sign, and then let x point to this new place, no matter who the original b pointed to.

 4. Everything is an object

Python uses an object model to store data, and any type of value is an object. All python objects have 3 characteristics: identity id , type type and value value .
Identity : Each object has its own unique identity, which can be obtained using the built-in function id(). This value can be thought of as the memory address of the object.
Type : The type of an object determines what type of value the object can hold, what operations it can perform, and what rules it follows. type() function to check the type of python object.
Value : The data item represented by the object.

>>> a = 1
>>> id(a)
140068196051520
>>> b = 2
>>> id(b)
140068196051552
>>> c = a
>>> id(c)
140068196051520
>>> c is a
True
>>> c is not b
True

The operators is and is not are judged by the return value (namely identity) of id(), that is, whether they are the "label" of the same object.

 

This article comes from a document I saw. The specific source is not available. I think it is relatively clear about the reference. References and mutable objects Immutable objects are more important in Python, because in the following learning, they will be used intentionally or unintentionally.

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324761067&siteId=291194637