欢迎访问宙启技术站
智能推送

Python中函数参数的传递方式和区别

发布时间:2023-06-18 09:36:25

在Python中,函数的参数传递方式主要有两种,分别是值传递和引用传递。这两种传递方式的区别在于传递的是参数的值还是引用(地址)。

值传递:将参数的值(副本)传递到函数内部进行操作,不会改变原始参数的值。

引用传递:将参数的引用(地址)传递到函数内部进行操作,会直接改变原始参数的值。

下面分别从参数的类型、传递方式以及实例三个方面进行详细介绍。

参数类型

函数的参数一般分为两种类型:可变类型和不可变类型。

可变类型:包括List(列表)、Dict(字典)等,在函数内部可以直接修改它们的值。

不可变类型:包括int(整型)、str(字符串)、tuple(元组)等,在函数内部不能直接修改它们的值。

传递方式

值传递

值传递是指将参数的值(副本)传递到函数内部进行操作。这种传递方式可以保证函数内部的操作不会影响原始参数的值。

对于不可变类型的参数,采用值传递方式,函数内部对参数进行重新赋值操作时不会影响到原始参数的值。

例如:

def func(x):
    x = x + 1
    print('x的值为:', x)

a = 1
func(a)
print('a的值为:', a)

运行结果为:

x的值为: 2
a的值为: 1

可以看到,在函数内部对x进行了重新赋值操作,但是a的值并没有改变,仍然是1。

对于可变类型的参数,采用值传递方式,函数内部可以对它们进行修改操作,但是修改后的结果仅仅只是对函数内部的参数产生了影响,不会影响到原始参数的值。

例如:

def func(lst):
    lst.append(4)
    print('lst的值为:', lst)

l = [1, 2, 3]
func(l)
print('l的值为:', l)

运行结果为:

lst的值为: [1, 2, 3, 4]
l的值为: [1, 2, 3, 4]

可以看到,在函数内部对lst进行了append操作,但是l的值也发生了改变,这是因为l和lst引用的是同一个列表对象。但是如果在函数内部重新对lst进行赋值操作,l的值不会发生改变。

例如:

def func(lst):
    lst = [1, 2, 3, 4]
    print('lst的值为:', lst)

l = [1, 2, 3]
func(l)
print('l的值为:', l)

运行结果为:

lst的值为: [1, 2, 3, 4]
l的值为: [1, 2, 3]

可以看到,虽然在函数内部对lst进行了重新赋值操作,但是l的值并没有发生改变。

引用传递

引用传递是指将参数的引用(地址)传递到函数内部进行操作,会直接改变原始参数的值。

对于可变类型的参数,采用引用传递方式,函数内部对它们进行修改操作会直接改变原始参数的值。

例如:

def func(lst):
    lst.append(4)
    print('lst的值为:', lst)

l = [1, 2, 3]
func(l)
print('l的值为:', l)

运行结果为:

lst的值为: [1, 2, 3, 4]
l的值为: [1, 2, 3, 4]

可以看到,在函数内部对lst进行了append操作,l的值也发生了改变,这是因为l和lst引用的是同一个列表对象。

对于不可变类型的参数,采用引用传递方式,函数内部对它们进行修改操作时会直接报错。

例如:

def func(x):
    x += 1
    print('x的值为:', x)

a = 1
func(a)
print('a的值为:', a)

运行结果为:

TypeError: 'int' object is not iterable

可以看到,函数内部对x进行+=1操作时直接报错了。

实例

下面通过一个案例来进一步说明函数参数传递方式的区别。

在这个案例中,我们定义一个函数swap,用来交换两个变量的值,然后测试不同参数类型和传递方式的表现。

首先,我们测试一下两个int类型变量a和b的交换:

def swap(x, y):
    x, y = y, x
    print('x的值为:', x)
    print('y的值为:', y)

a = 1
b = 2
swap(a, b)
print('a的值为:', a)
print('b的值为:', b)

运行结果为:

x的值为: 2
y的值为: 1
a的值为: 1
b的值为: 2

可以看到,虽然在函数内部对x和y进行了交换操作,但是a和b的值仍然没有发生改变。

测试一下两个list类型变量lst1和lst2的交换:

def swap(x, y):
    x, y = y, x
    print('x的值为:', x)
    print('y的值为:', y)

lst1 = [1, 2, 3]
lst2 = [4, 5, 6]
swap(lst1, lst2)
print('lst1的值为:', lst1)
print('lst2的值为:', lst2)

运行结果为:

x的值为: [4, 5, 6]
y的值为: [1, 2, 3]
lst1的值为: [1, 2, 3]
lst2的值为: [4, 5, 6]

可以看到,在函数内部对lst1和lst2进行了交换操作,但是lst1和lst2的值并没有发生改变。

最后,我们测试一下两个dict类型变量dic1和dic2的交换:

def swap(x, y):
    x, y = y, x
    print('x的值为:', x)
    print('y的值为:', y)

dic1 = {'a': 1, 'b': 2}
dic2 = {'c': 3, 'd': 4}
swap(dic1, dic2)
print('dic1的值为:', dic1)
print('dic2的值为:', dic2)

运行结果为:

x的值为: {'c': 3, 'd': 4}
y的值为: {'a': 1, 'b': 2}
dic1的值为: {'c': 3, 'd': 4}
dic2的值为: {'a': 1, 'b': 2}

可以看到,虽然在函数内部对dic1和dic2进行了交换操作,但是dic1和dic2的值仍然没有发生改变。

通过以上实例,我们可以看出,函数参数传递方式对不同类型参数的影响是不一样的,需要根据实际情况灵活使用。