可以将python中常见数据类型按照可变与不可变大致分为两类

可变类型

不可变类型

列表、字典、类

数值型、字符串、元组

理解可变与不可变
  熟悉python的都知道,像字符串和元组创建之后是无法更改的,如果更改那么就只能替换掉,也就是说丢弃原来的存储空间,将变量名链接到新的空间中。而像list和dict是支持增删改的。
以list和tuple增加元素的操作为例(用内置函数 id(var) 来查看变量内存地址)

x   = [1,2]
print('mutable var:list')
print('original:', id(x))
x.append(10)
print('modifed:', id(x))

print('\n')

print('immutable var:tuple')
y = tuple([1, 2])
print('original:', id(y))
y+=(10,)
print('modified:', id(y))

reuslt:

mutable var:list
original: 140611793965640 [1, 2]
modifed: 140611793965640 [1, 2, 10]


immutable var:tuple
original: 140611829612104 (1, 2)
modified: 140611793818824 (1, 2, 10)

由结果可见,虽然都添加了一个元素,但是list的存储首地址不变。tuple类型的变量也修改成功,但是通过替换来实现,也就是变量指向新的存储地址。

如何修改函数参数
  来看两个例子

#向函数传入一个不可变类型变量作为参数
var = 10
def func(var):
   var = 20
   print('var in func:', var)
   
print('global var:', var)
func(var)
print('global var after func modified:', var)
global var: 10
var in func: 20
global var after func modified: 10

上述例子说明,对传入函数的不可变类型变量进行更改,并不影响函数作用域之外该变量的原始值。

那么再来看看传入可变变量是什么情形

#传入一个可变变量
lst = [1,2]

def func(var):
    var.append(100)
    print('var in func:', var)
    
print('global var:', lst)
func(lst)
print('global var after func modified:', lst)

result

global var: [1, 2]
var in func: [1, 2, 100]
global var after func modified: [1, 2, 100]

从结果来看,在函数中对传入的list变量进行修改,使得函数作用域之外的变量也发生了改变。这与第一个实验传入不可变变量的结果正好相反。

初步结论: 从上述两个实验中可以初步得出一个结论,在函数中修改不可变变量,不会影响函数之外的变量,而修改可变变量能够影响函数之外的变量。

那么再来看一个例子

#传入一个可变变量
lst = [1,2]

def func(var):
    var = list([100,100])  #区别在这里
    print('var in func:', var)
    
print('global var:', lst)
func(lst)
print('global var after func modified:', lst)

result

global var: [1, 2]
var in func: [100, 100]
global var after func modified: [1, 2]