Are parameters passed by value or by reference in Python?

In C/C++, pass-by-value and pass-by-reference are two ways of passing function parameters. How are parameters passed in Python? Before answering this question, it is better to look at two pieces of code.

Code snippet 1:

def foo(arg):
    arg = 2
    print(arg)

a = 1
foo(a)  # 输出:2
print(a) # 输出:1

Students who read Code 1 may say that parameters are passed by value.

Code snippet 2:

def bar(args):
    args.append(1)

b = []
print(b)# 输出:[]
print(id(b)) # 输出:4324106952
bar(b)
print(b) # 输出:[1]
print(id(b))  # 输出:4324106952

After reading code snippet 2, some people may say that the parameter is passed by reference. Then the question is, is the parameter passed by value or by reference or neither? In order to clarify this problem, first understand the relationship between variables and objects in Python.

Variables and objects

Everything in Python is an object, numbers are objects, lists are objects, functions are objects, and everything is an object. The variable is a reference (also called a name or label) of an object, and the operations of the object are all done by reference. For example, [] is an empty list object, and the variable a is a reference to that object

a = []
a.append(1)

In Python, "variable" is more accurately called "name", and assignment operation = is to bind a name to an object. It's like adding a label to an object.

a = 1

Insert picture description here

Assigning the integer 1 to the variable a is equivalent to binding an a label to the integer 1.

a = 2

Insert picture description here
Assigning the integer 2 to the variable a is equivalent to tearing off the label a from the original integer 1 and pasting it to the integer 2.

b = a

Insert picture description here
Assigning variable a to another variable b is equivalent to attaching two labels a and b to object 2. Object 2 can be operated on through these two variables.

The variable itself has no type information, the type information is stored in the object, which is very different from the variable in C/C++ (a variable in C is a memory area)

Function parameters

In Python functions, parameter passing is essentially an assignment operation, and assignment operation is a process of binding names to objects. After understanding the nature of assignment and parameter passing, let’s analyze the previous two pieces of code.

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
def foo(arg):
    arg = 2
    print(arg)

a = 1
foo(a)  # 输出:2
print(a) # 输出:1

Insert picture description here
In code segment 1, the variable a is bound to 1. When the function foo(a) is called, it is equivalent to assigning arg=1 to the parameter arg. At this time, both variables are bound to 1. After re-assigning arg to 2 in the function, it is equivalent to tearing off the arg label on 1 and sticking it to the body of 2, while the other label a on 1 always exists. Therefore print(a) is still 1.

Look at code snippet 2 again

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
def bar(args):
    args.append(1)

b = []
print(b)# 输出:[]
print(id(b)) # 输出:4324106952
bar(b)
print(b) # 输出:[1]
print(id(b))  # 输出:4324106952

Insert picture description here
Before the append method is executed, both b and arg point to (bind) the same object. When the append method is executed, there is no reassignment operation, and there is no new binding process. The append method just inserts an element into the list object, and the object is still that Object, but the content inside the object has changed. Because b and arg are both bound to the same object, the execution of the b.append or arg.append method essentially operates on the same object, so the content of b has changed after the function is called (but the id has not changed) , Still the original object)

Finally, back to the question itself, is it by value or by reference? It is not accurate to say that passing by value or passing by reference. If there is an exact name, it is called call by object. If you are an interviewer, you have to check whether the candidate is familiar with Python function parameter passing. Instead of discussing the literal meaning, it is better to get some actual code.
show me the code

def bad_append(new_item, a_list=[]):
    a_list.append(new_item)
    return a_list

This code is the most common mistake for beginners, using mutable objects as the default values ​​of the parameters. After the function is defined, the default parameter a_list will point (bind) to an empty list object. Each time the function is called, the same object is appended. Therefore, writing this way will have potential bugs, and the same call method will return different results.

>>> print bad_append('one')
['one']
>>> print bad_append('one')
['one', 'one']

Insert picture description here
The correct way is to specify the default value of the parameter as None

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
def good_append(new_item, a_list=None):
    if a_list is None:
        a_list = []
    a_list.append(new_item)
    return a_list

Insert picture description here

Guess you like

Origin blog.csdn.net/sinat_38682860/article/details/109311375