python的一切数据类型都是对象。但是python的对象分为不可变对象和可变对象。python的变量是引用,对python变量的赋值是引用去绑定该对象。
可变对象的数据发生改变,例如列表和字典,引用不会更改绑定对象,毕竟本身就是用于增删改查的,频繁地产生新对象必然导致开销巨大,只需要该对象内部变化就行;但对于绑定了不可变对象的引用,对象一旦改变就会使引用绑定新的对象。
这一点也会反应到函数的参数上。python的传值方式是“传对象”引用。python的函数,形参实际上是引用,实参便是对象绑定到该引用上。本质是形参会被作为函数的局部变量,在开辟的函数的栈内存中被声明。
简要来讲:
如果参数是数,则类似值传递,
如果参数是列表和字典,则类似引用传递。
每个对象都会有个id, 可以用id()验证以上说法:
这个函数的参数是列表,是可变对象。
def quicksort(nums):
print(id(nums))
if not nums:
return []
nums[0]=-1
print(id(nums))
return nums
print(quicksort([0,1,2,3]))
得到如下的值:
139851629622344
139851629622344
[-1, 1, 2, 3]
可看到nums的id在修改后不会改变
如果参数是数呢?
def quicksort(nums):
print(id(nums))
if not nums:
return []
nums=-1
print(id(nums))
return nums
print(quicksort(1))
10914496
10914432
-1
可以看到id发生了变化
所以,在写python的函数的时候,时不时会遇到global variable的问题,这也与pythond的可变对象和不可变对象有关。后面会详解。