今天在看函数实参和形参时,有这样一段话:
根据实际参数的类型不同,可以分为将实际参数的值传递给形式参数和将实际参数的引用传递给形式参数两种。其中,当实际参数为不可变对象时,进行的是值传递,也就是改变形式参数的值,实际参数的值不变;当实际参数为可变对象时,进行的是引用传递,也就是改变形式参数的值,实际参数的值也一同改变。
以前我也没有注意到这个问题,今天在理解和验证这段话的基础上,对pyhon中可变对象和不可变对象也进行一下学习。
一.函数值传递和引用传递
由上面例子可以发现:
值传递没有改变实参,仅仅改变了形参;但是引用传递不仅改变了形参,也改变了实参。
所以我认为默认参数必须指向不可变对象也是这个原因,不然每次调用结果都不一样岂不是出大问题了,不会报错,但结果却是错的。
二.python中可变对象与不可变对象
不可变对象:
该对象所指向的内存中的值不能被改变。所以改变某个变量时,是把原来的值复制一份后再改变,也就是又用了一个新地址,变量指向这个新的地址。比如:数值类型(int和float)、字符串str、元组tuple。
举例:(以字符串为例,数值类型类似)
从以上代码可知:
改变字符串值时,内存地址发生了变化。
元组tuple需要单独说一下,稍微有些不一样:
相同内容不同变量内存地址不一样,但这并不可以说明它是可变对象,因为其在修改值时内存地址发生了变化,这跟字符串是一致的。它依然是不可变对象。
可变对象:
该对象所指向的内存中的值可以被改变。所以改变某个变量时,是原来的值直接发生改变,并没有复制一份到新地址这样的操作。比如列表list、字典dict、集合set。
举例:(以列表为例)
可以发现在修改列表值时列表在原地址内容被直接修改。那我们有时候不想直接修改呢?毕竟这是直接被取代了,有点粗暴。没有关系,列表还有复制操作,啊哈哈哈。
原来列表并没有改变,✌