第七章python对象引用、可变性和垃圾回收

1.python变量是什么

  • python的变量实质是一个指针,而java普通变量是一个容器直接存入值。

为什么b也变了呢,由于a,b同时指向同一个地址,导致a指向的内容改变也会让b改变,id()获得对象所指向的内存中的地址,如果是对象本身的地址的话a,b应该是不相同的。

1 a = [1, 2, 3]
2 b = a
3 # a和b实质是指针都指向同一个地址,修改a同时会修改b
4 print(id(a), id(b))  # 54866344 54866344
5 print(a is b)   # True
6 
7 a.append(2)
8 print(a, b)  # [1, 2, 3, 2] [1, 2, 3, 2]

注:python变量生成步骤

  • 先建立对象[1,2,3,4] 赋值一个地址:19333544
  • 让a指向这个19333544地址
  • 再建立对象[1,2,3,4] 赋值一个地址:193335480
  • 让b指向这个193335480地址
  • 让c指向与a指向相同的地址

a和b指向不同的对象,c和a指向相同对象

1 a = [1, 2, 3, 4]
2 b = [1, 2, 3, 4]
3 c = a
4 print(id(a), id(b), id(c))  # 19333544 19333480 19333544

关键点:

对于小整数和小串字符建立都指向同一个地址,其他都是不同地址

1 a = 1
2 b = 1
3 c = a
4 print(id(a), id(b), id(c))  # 1399769008 1399769008 1399769008
5 
6 a = "abc"
7 b = "abc"
8 c = a
9 print(id(a), id(b), id(c))  # 24048032 24048032 24048032

2.==和is的区别

  • ==:比较的是两个对象的值是否相等
  • is:比较的是两个对象的地址是否相等,比较id(a) == id(b)
1 a = [1, 2, 3, 4]
2 b = [1, 2, 3, 4]
3 c = a
4 print(id(a), id(b), id(c))  # 19333544 19333480 19333544
5 print(a is b, a is c, b is c)  # False True False
6 print(a == b, a == c, b == c)  # True True True

3.del语句和垃圾回收

  • CPython使用垃圾回收算法是引用计数的方式

先建立a,让b,c同时指向a所指向的内存此时引用计数值为3,del a之后引用计数为2,最后程序结束删除对象

 1 class A:
 2     def __init__(self, name):
 3         self.name = name
 4         print("init:" + name)
 5 
 6     def __del__(self):
 7         print("del:" + self.name)
 8 
 9 
10 a = A("a")  # init:a
11 b = a
12 c = a
13 del a
14 c.name = "c"
15 print(b.name)  # c
16 b.name = "b"
17 print(b.name)  # b  
最后执行del:b

4.一个经典错误

猜你喜欢

转载自www.cnblogs.com/zhihaospace/p/12089255.html
今日推荐