如何在Python中通过值或引用传递参数?
在Python中,参数传递有两种方式,分别是传值和传引用。在使用函数时,我们需要知道这两种方式的区别,并根据不同情况选择合适的方式传递参数。
更多Python教程,请阅读:Python 教程
传值
传值是指函数调用时,实参将自己的值传给形参,此时形参和实参是两个独立的变量。在函数内部改变形参的值不会影响到实参的值。
让我们来看看一个例子:
def change_num(num):
num += 10
print("函数内部num的值为:", num)
num = 20
change_num(num)
print("函数外部num的值为:", num)
输出:
函数内部num的值为: 30
函数外部num的值为: 20
在这个例子中,我们定义了一个函数change_num
,并将变量num
作为实参传递给它。在函数内部,我们将形参num
加上 10,然后打印出它的值。在函数外部,我们再次打印变量num
的值。
我们可以看到,在函数内部num
的值被改变成了 30,但是在函数外部num
的值仍然是 20,这说明我们改变形参num
的值并没有影响到实参num
的值。
传引用
传引用是指函数调用时,实参将自己的引用传给形参,此时形参和实参指向的是同一个数据对象。在函数内部改变形参的值会影响到实参的值。
让我们用一个例子来说明:
def change_list(my_list):
my_list.append(4)
print("函数内部my_list的值为:", my_list)
my_list = [1, 2, 3]
change_list(my_list)
print("函数外部my_list的值为:", my_list)
输出:
函数内部my_list的值为: [1, 2, 3, 4]
函数外部my_list的值为: [1, 2, 3, 4]
在这个例子中,我们定义了一个函数change_list
,并将列表my_list
作为实参传递给它。在函数内部,我们向形参my_list
中添加一个新元素 4,然后打印出它的值。在函数外部,我们再次打印列表my_list
的值。
我们可以看到,在函数内部my_list
的值被改变成了[1, 2, 3, 4],在函数外部同样也是[1, 2, 3, 4],这说明我们改变形参my_list
的值影响到了实参my_list
的值。
怎么选择传值和传引用?
在Python中,我们无法直接选择传值或传引用,这取决于传递的是可变对象还是不可变对象。
不可变对象包括数字、字符串、元组等,它们传递的都是值。如果在函数中改变了不可变对象的值,相当于新建了一个对象,不会影响到原来的对象。
可变对象包括列表、集合、字典等,它们传递的是引用。如果在函数中改变了可变对象的值,相当于原来的对象被修改了。
让我们看看一个例子:
def change_str(s):
s += 'world'
return s
def change_list(my_list):
my_list.append(4)
return my_list
s = 'hello'
my_list = [1, 2, 3]
print("改变前的s:", s)
print("改变前的my_list:", my_list)
s = change_str(s)
my_list = change_list(my_list)
print("改变后的s:", s)
print("改变后的my_list:", my_list)
输出:
改变前的s: hello
改变前的my_list: [1, 2, 3]
改变后的s: helloworld
改变后的my_list: [1, 2, 3, 4]
在这个例子中,我们定义了两个函数change_str
和change_list
,并分别将字符串s
和列表my_list
作为实参传递给它们。在函数内部,我们改变形参的值,然后将它们返回。在函数外部,我们再次打印变量s
和my_list
的值,观察它们是否被改变。
我们可以看到,改变前后的s
值不相同,这说明在函数内部修改s
的值并没有影响到函数外部s
的值。而改变前后的my_list
值相同,这说明在函数内部修改my_list
的值影响到了函数外部my_list
的值。
总结
在Python中,函数参数传递有两种方式:传值和传引用。传值是指函数调用时,实参将自己的值传给形参,此时形参和实参是两个独立的变量。传引用是指函数调用时,实参将自己的引用传给形参,此时形参和实参指向的是同一个数据对象。
在选择传值和传引用时,我们需要根据传递的是可变对象还是不可变对象来进行选择。不可变对象传递的是值,如果在函数中改变了不可变对象的值,相当于新建了一个对象,不会影响到原来的对象。可变对象传递的是引用,如果在函数中改变了可变对象的值,相当于原来的对象被修改了。