Python中函数参数的传递方式和区别
在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的值仍然没有发生改变。
通过以上实例,我们可以看出,函数参数传递方式对不同类型参数的影响是不一样的,需要根据实际情况灵活使用。
