Is the parameter passing of Python function passing by value or by reference?

introduce

Today, the byte interviewer asked this question, asking: After the python function modifies the variable passed in, will it affect the value of the variable outside the function? My answer is that if the numpy array is passed in, it will change. The interviewer is probably not satisfied with this answer, so let's study this question seriously now.

Some blogs have given good conclusions ( Is python's parameter passing by value or by reference? Neither! ):

Python does not allow programmers to choose to use pass-by-value or pass-by-reference. Python parameter passing is definitely the way of "passing object reference". This method is equivalent to a combination of passing by value and passing by reference. If the function receives a reference to an immutable object (number, character or tuple), it cannot modify the original object directly – it is equivalent to passing the object by 'passing by value'. If the function receives a reference to a mutable object (dictionary, list), it can modify the original value of the object – equivalent to passing the object by 'passing by reference'.

Now let's practice according to this conclusion. In the process, I also discovered some new things.
My Python version is: 3.8.8

immutable object

Number

def func(a, b):
    a += a
    b += 100
    print('a={}, b={}'.format(a, b))

a = 1
b = 2
print('a={}, b={}'.format(a, b))
func(a, b)
print('a={}, b={}'.format(a, b))

Print result:

a=1, b=2
a=2, b=102
a=1, b=2

It can be seen that modifying the digital variable in the function will not affect the external variable

String (String)

def func(a, b):
    a = '_'.join([a, a])
    b += '100'
    print('a={}, b={}'.format(a, b))

a = '1'
b = '2'
print('a={}, b={}'.format(a, b))
func(a, b)
print('a={}, b={}'.format(a, b))

Print result:

a=1, b=2
a=1_1, b=2100
a=1, b=2

It can be seen that modifying the string variable in the function will not affect the outside variable

Tuple

def func(a, b):
    # a[0] = 100  # 会报错
    b += (100, 100)
    print('a={}, b={}'.format(a, b))

a = (1, 1)
b = (2, 2)
print('a={}, b={}'.format(a, b))
func(a, b)
print('a={}, b={}'.format(a, b))

Print result:

a=(1, 1), b=(2, 2)
a=(1, 1), b=(2, 2, 100, 100)
a=(1, 1), b=(2, 2)

It can be seen that modifying the tuple variables in the function will not affect the variables outside

mutable object

list

def func(a, b, c):
    a[0] = 100 # 修改值
    b.append(100) # 添加新的值
    c = [100, 100] # 重新赋值
    print('a={}, b={}, c={}'.format(a, b, c))

a = [1, 1]
b = [2, 2]
c = [3, 3]
print('a={}, b={}, c={}'.format(a, b, c))
func(a, b, c)
print('a={}, b={}, c={}'.format(a, b, c))

Print result:

a=[1, 1], b=[2, 2], c=[3, 3]
a=[100, 1], b=[2, 2, 100], c=[100, 100]
a=[100, 1], b=[2, 2, 100], c=[3, 3]

It can be seen that for list variables, if the value is modified or new elements are added, the external variables will be affected, but if the value is reassigned, it will not! ! !

Dictionary (Dict)

def func(a, b, c):
    a[1] = 100 # 修改键值对
    b[1] = 100 # 添加新的键值对
    c = {
    
    100: 100} # 重新赋值
    print('a={}, b={}, c={}'.format(a, b, c))

a = {
    
    1: 1}
b = {
    
    2: 2}
c = {
    
    3: 3}
print('a={}, b={}, c={}'.format(a, b, c))
func(a, b, c)
print('a={}, b={}, c={}'.format(a, b, c))

Print result:

a={
    
    1: 1}, b={
    
    2: 2}, c={
    
    3: 3}
a={
    
    1: 100}, b={
    
    2: 2, 1: 100}, c={
    
    100: 100}
a={
    
    1: 100}, b={
    
    2: 2, 1: 100}, c={
    
    3: 3}

Same as the list, if you modify the value or add new elements, it will affect the external variables, but if you reassign it, it will not! ! !

numpy array

import numpy as np
def func(a, b, c):
    a[0] = 100 # 修改值
    b = np.concatenate((b, b), 0) # 添加新的值
    c = np.array([100, 100]) # 重新赋值
    print('a={}, b={}, c={}'.format(a, b, c))

a = np.array([1, 1])
b = np.array([2, 2])
c = np.array([3, 3])
print('a={}, b={}, c={}'.format(a, b, c))
func(a, b, c)
print('a={}, b={}, c={}'.format(a, b, c))

Print result:

a=[1 1], b=[2 2], c=[3 3]
a=[100   1], b=[2 2 2 2], c=[100 100]
a=[100   1], b=[2 2], c=[3 3]

Same as the list, if the value is modified, it will affect the external variables, but if it is reassigned (concatenate is also reassigned) it will not! ! !

in conclusion

  1. When the parameters passed in by the function are immutable objects (numbers, strings, tuples), any operations done in the function will not affect the variables outside
  2. When the parameter passed in by the function is a mutable object (list, dictionary, and numpy array), the parameter passed in at this time is actually the address pointer of the variable. Modifying the variable on this will naturally affect the external variables. For example, when modifying elements and adding new elements to variables in the function (without opening up new space), it will affect the variables outside. But if it is a reassignment, it will not be affected, because the repeated assignment has opened up a new space for the variable, instead of modifying the variables in between.

Guess you like

Origin blog.csdn.net/qq_33757398/article/details/125773117