Python中变量传递时的引用和赋值

 Python中不明确区分赋值和应用,一般对静态变量的传递为赋值,对动态变量的传递为引用。(注,对静态变量首次传递时也是应用,当需要修改静态变量时,因为静态变量不能改变,所以需要生成一个新的空间存储数据)个人觉得分清楚规则即可比较容易的区别。


字符串,整数,元组均为静态变量

列表,字典为动态变量。


以下示例在Python 2.7环境下演示,id()函数可显示变量内存地址

例1:整数传递

a = 4
print 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:列表的地址存储(以下为个人理解,未查源代码,如有错误请指正)

  1. a = [4, 5]
  2. print "address a=", id(a)
  3. print "address a0=", id(a[0])
  4. print "address a1=", id(a[1])
  5. b = a
  6. b[0] = 6
  7. print "a=", a
  8. print "b=", b
  9. print "address a=", id(a)
  10. print "address b=", id(b)
  11. print "address a0=", id(a[0])
  12. print "address a1=", id(a[1])
  13. b[1] = "str"
  14. print "a=", a
  15. print "b=", b
  16. print "address a=", id(a)
  17. print "address b=", id(b)
  18. print "address a0=", id(a[0])
  19. print "address a1=", id(a[1])

>>>

  1. address a= 24415912
  2. address a0= 23648112
  3. address a1= 23648088
  4. a= [6, 5]
  5. b= [6, 5]
  6. address a= 24415912
  7. address b= 24415912
  8. address a0= 23648064
  9. address a1= 23648088
  10. a= [6, 'str']
  11. b= [6, 'str']
  12. address a= 24415912
  13. address b= 24415912
  14. address a0= 23648064
  15. 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发生了改变,指向一个新的数据地址


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值