Python中不明确区分赋值和应用,一般对静态变量的传递为赋值,对动态变量的传递为引用。(注,对静态变量首次传递时也是应用,当需要修改静态变量时,因为静态变量不能改变,所以需要生成一个新的空间存储数据)个人觉得分清楚规则即可比较容易的区别。
字符串,整数,元组均为静态变量
列表,字典为动态变量。
以下示例在Python 2.7环境下演示,id()函数可显示变量内存地址
例1:整数传递
a = 4print id(a) #id函数显示变量内存地址
b = a
print id(b)
b = 6
print id(b)
>>>
19691376
19691376
19691328
说明,
1.a被赋值4
2.b是a的引用
3.b改变,因为此时b指向的是一个静态变量4,所以给b赋值时,先将6存入一个和4不同的地址,然后b再指向6的地址
例2:变量传递
a = "mm"print id(a)
b = a
print id(b)
b = "nn"
print id(b)
>>>
37313312
37313312
37313352
说明:
1.a为一个指向字符串的变量名
2.a传递给b时,b为一个引用指向和a相同的地址
3.当b被赋给一个新字符串值时,因为b指向的"mm"是一个静态变量,所以生成一个新空间存放"nn",然后b指向"nn"
例3:列表的地址存储(以下为个人理解,未查源代码,如有错误请指正)
- a = [4, 5]
- print "address a=", id(a)
- print "address a0=", id(a[0])
- print "address a1=", id(a[1])
- b = a
- b[0] = 6
- print "a=", a
- print "b=", b
- print "address a=", id(a)
- print "address b=", id(b)
- print "address a0=", id(a[0])
- print "address a1=", id(a[1])
- b[1] = "str"
- print "a=", a
- print "b=", b
- print "address a=", id(a)
- print "address b=", id(b)
- print "address a0=", id(a[0])
- print "address a1=", id(a[1])
>>>
- address a= 24415912
- address a0= 23648112
- address a1= 23648088
- a= [6, 5]
- b= [6, 5]
- address a= 24415912
- address b= 24415912
- address a0= 23648064
- address a1= 23648088
- a= [6, 'str']
- b= [6, 'str']
- address a= 24415912
- address b= 24415912
- address a0= 23648064
- address a1= 140688190862360
说明:
从输出的1,2,3行看出,a的地址>a[0]的地址>a[1]的地址,而且a[0]和a[1]地址间相差较远,所以python中的列表绝对不是c中的数组,应该是个链表。(从python列表具有append()函数也可以看出)
命令第5行a传递给b时,从输出6,7行看,a和b指向了同一个地址,b为a的一个引用,a,b的值应该是指向链表头的指针。
命令第6行,b[0]值发生改变,从输出4,5行看,a,b内容同时都发生改变,从输出6,7行a,b指向的还是同一个地址,从输出7行看a[0]的地址发生了改变,所以应该时链表的第一个节点被替换(即使变量类型兼容),所以也可以理解为什么python可以不关注变量类型。输出第8行为a[1]的地址,没有发生改变
命令第13行,b[1]被改变,分析同上,a,b指向的同一个链表的尾元素被替换
例4:列表传递(引用)
a = [4]print id(a)
b = a
print id(b)
b[0] = 6
print id(b)
>>>
43351720
43351720
43351720
说明;
同上例理解
例5:列表赋值
a = [4]print id(a)
b = a[:]
print id(b)
b[0] = 8
print id(b)
>>>
22863528
23030888
23030888
说明:
1.a指向一个动态变量列表
2.b得到a列表的一个copy存储在一个新的空间,b指向一个新地址(b = a 和b=a[:]的区别可从 ,b=a,b=a[1:3]的区别进行理解)
3.b的第一个元素赋值8,不影响a
例6:字典引用
a = {"i":99}print id(a)
b = a
print id(b)
b["o"] = 8
print id(b)
print "a=", a
print "b=", b
>>>
28841616
28841616
28841616
a= {'i': 99, 'o': 8}
b= {'i': 99, 'o': 8}
说明:
1.a指向一个动态变量
2.b为a的一个引用
3.b新增了一个变两,a也新增
例7:字典赋值
a = {"i":99}print id(a)
b = a.copy()
print id(b)
b["o"] = 8
print id(b)
print "a=", a
print "b=", b
>>>
16033424
16063424
16063424
a= {'i': 99}
b= {'i': 99, 'o': 8}
说明:
1.a指向一个动态变量
2.b为a的一个拷贝,指向一个新地址
3.b新增了一个变量,a不变
例8:不同类型变量传递
a = "mm"
print id(a)
b = a
print id(b)
b = 8
print id(b)
print "a=", a
print "b=", b
>>>
11687096
11687096
10692368
a= mm
b= 8
说明:
1.a指向一个静态
2.b为a的一个应用,指向和a相同的地址
3.b发生了改变,指向一个新的数据地址