python 05 关于对python中引用的理解

Posted wangjiepy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python 05 关于对python中引用的理解相关的知识,希望对你有一定的参考价值。

  数据的在内存中的地址就是数据的引用。
  如果两个变量为同一个引用,那么这两个变量对应的数据一定相同;
  如果两个变量对应的数据相同,引用不一定相同。
  通过id(数据)可以查看数据对应的地址,修改变量的值,其实是在修改变量的引用。
  数据可以分为:可变类型与不变类型
    可变类型:
      如果修改了数据的内容,数据的地址没有发生改变.
      有列表,字典,set集合
    不可变类型:
      如果修改了数据的内容,数据的地址发生改变.
      有字符串,元组,数字
  当python解释器首次启动时,会把小数字(-5~256)和短字符串(长度小于21)缓存到缓冲区中,当在程序中使用这些数字和字符串时,就直接从缓存区中取。
    m = 300
    n = 300
    print(id(m)) # 1811121856
    print(id(n))
    不在小数字或者小字符串范围内的数据,会在第一次使用时缓存起来
    m = 300
    n = 300
    print(id(m)) # 2345027009360
    print(id(n)) # 2345027009360

演示:
1.
变量a实际存储的是1的引用(地址)(在程序执行过程中a被编译为一条指令)
a = 1
b = a
print(id(a)) # 1820749280
print(id(b)) # 1820749280
a =2 # 修改不可变类型(的引用)
print(id(a)) # 1820749312 a的id已经改变
print(id(b)) # 1820749280
print(a,b)

a = [1, 2,[3,5]]
b = a
print(id(a)) # 1758314288776
print(id(b)) # 1758314288776
# a.append(3)
a[0] = 6
a[2][0] = 1
b[2][1] = 6
print(id(a)) # 1758314288776 注意a与b始终指向同一个地址
print(id(b)) # 1758314288776
print(a) # [6, 2, [1, 6]]
print(b) # [6, 2, [1, 6]]

2.

list = []
dict = {"name":"wangjie","age":23}
print(id(dict))
a = 10
list.append(dict) # 把dict的引用加入到list中 0x111 的内容是(指向){"name":"wangjie","age":23}
list.append(a) # 把a的引用加入到list中 0x222 的内容是(指向)10
print(list) # list[0] 为0x111 ,内容是(指向)数据{"name":"wangjie","age":23},list[1]的内容0x222,内容是(指向)数据10
a = 20 # 修改了a的值 a的引用发生的变化 0x333
   # 但不影响list中的引用指向的值 还是指向0x111 指向{"name":"wangjie","age":23}
   # 和0x222 指向 10
print(list)
dict["name"] = "lili" #修改了dict的值 dict为可变数据类型,dict的引用不变,但指向发生变化0x指向0x111,但0x222已经变为{‘name‘: ‘lili‘, ‘age‘: 23}
print(list) # list[0]的内容是 0x111 , 指向数据{‘name‘: ‘lili‘, ‘age‘: 23},list[1]的内容为0x222指向数据 10

3.
list = []
list2 = []
m = 10
def func():
  global m
  m =20
  list2 = [1,2] # 不属于修改,修改需要通过方法,这种是覆盖全局变量list2
  list.append(1) # 通过append 方法修改,list的引用不变
  print(list2) # [1, 2]
print(list) # []
print(m) # 10
print(id(m)) # 1811115776

func() # [1, 2]

print(list) # [1]
print(list2) # []
print(m) # 20
print(id(m)) # 1811116096

4.

def log2():
  #info_dict = {} # 存储学生信息的字典若放在for循环外,则旧数据会被新数据覆盖
  info_list = []
  num = input("请输入要录入信息的数量")
  num = int(num)
  for i in range(num):
    info_dict = {} # 重新直接对info_dict 赋值,info_dict的引用发生改变 存储学生信息的字典要放在for循环# 内
    print("录入第%s 位信息" % (i + 1))
    name = input("输入姓名:")
    id = input("输入学号")
    info_dict["姓名"] = name
    info_dict["学号"] = id
    info_list.append(info_dict)
  print(info_list)
  for info in info_list:
    for k ,v in info.items():
      print(‘%s = %s‘ % (k,v))
log2()

5.

a = [1, 2]
b = [3, 4]
a.append(b) # [1,2,[3,4]]
b.append(a)
print(a) # [1, 2, [3, 4, [...]]]
print(b) # [3, 4, [1, 2, [...]]]

6.传递数据,传递的是数据对应的地址.

a = [[]] * 5 
print(a) [[],[],[],[],[]]
print(id(a)) # 2132205131400
print(id(a[0])) # 2132205131592
print(id(a[1])) # 2132205131592
a.append(1)
print(id(a)) # 2132205131400
print(a) # [[],[],[],[],[],1]
a[0].append(2)
print(id(a[0])) # 2132205131592
print(a) # [[2],[2],[2],[2],[2],1]
a[1].append(3)
print(id(a[1])) # 2132205131592
print(a) # [[2,3],[2,3],[2,3],[2,3],[2,3],1]

























































































































以上是关于python 05 关于对python中引用的理解的主要内容,如果未能解决你的问题,请参考以下文章

python怎么进行内存管理的?

理解python变量赋值[重复]

Python装饰器的通俗理解

关于 python 变量的几点说明

python-闭包的理解

在python中查找对对象的所有引用