Python中的函数参数传递方式是“传对象引用”,可以理解为“值传递”和“引用传递”的混合体。
在Python中,所有的数据类型都是对象。如果函数参数是不可变对象(如整数、字符串、元组),那么传递的就是对象的值,即“值传递”。因为不可变对象一旦创建,对象内的内容是不可改变的,所以在函数内部的参数值改变,并不会影响到原来的对象。
如果函数参数是可变对象(如列表、字典、自定义的类实例等),那么传递的就是对象的引用,即“引用传递”。函数内部对参数进行的操作,如添加、删除或其他修改,都会影响到原来的对象。
def change_list(lst):
lst.append(1)
def change_int(i):
i += 1
lst = [0]
i = 0
change_list(lst)
change_int(i)
print(lst) # 输出:[0, 1]
print(i) # 输出:0
Python中的可变对象与不可变对象:
不可变对象:整型(int)、浮点型(float)、布尔型(bool)、字符串(str)、元组(tuple)、冻结集合(frozenset)
不可变对象一旦创建,其状态就不能改变。也就是说,你不能在不可变对象上执行添加、删除、修改等操作。不可变对象的这种特性,使得我们可以安全地进行hash操作,将不可变对象用作字典的键或者添加到集合中。线程安全,不可变对象在多线程环境中也更为安全,因为它们的状态不会被其他线程改变。
可变对象:列表(list)、集合(set)、字典(dict)、bytearray、自定义的类(如果类的属性可以修改)
可变对象在创建后,其状态可以改变。也就是说,你可以在可变对象上执行添加、删除、修改等操作。可变对象的这种特性,使得我们可以灵活地对对象进行操作,并且不需要每次操作都创建一个新的对象。在多线程编程时,通常需要使用锁或者其他同步机制来保护可变对象的状态。
"值传递"和"引用传递"是两种函数参数传递的方式。
- 值传递(Value Passing): 当函数调用时,实参把它的值传递给形参。在这种情况下,改变形参的值并不会影响到实参。值传递可以看作是原始数据的一个副本,函数内对参数的修改不会影响到原始数据。
? 例如,C和C++中的基本数据类型(int,char等)和自定义的类对象,都是通过值传递的方式传递给函数。
- 引用传递(Reference Passing): 与值传递不同,引用传递是将实参的地址传递给形参。在这种情况下,对形参的任何操作都会影响到实参的值。引用传递可以看作是原始数据的一个别名或引用,函数内对参数的修改会直接影响到原始数据。
? 例如,Java中对象的传递就是引用传递,Python中的列表和字典等可变对象也是通过引用传递的方式传递给函数。
? 总结来说,值传递是传递对象的副本,修改不会影响原始对象;引用传递是传递对象的地址,修改会影响原始对象。