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

0.python中的数据类型

(1)python3中有六个标准的数据类型

  • Number(数值):int、float、bool、complex
  • String(字符串): str = 'Runoob' 
  • List(列表): list = [ 'abcd', 786 , 2.23, 'runoob', 70.2 ] 
  • Tuple(元组): tuple = ( 'abcd', 786 , 2.23, 'runoob', 70.2 ) 
  • Set(集合):
    {'Mary', 'Jim', 'Rose', 'Jack', 'Tom'}
  • Dictionary(字典):
    tinydict = {'name': 'runoob','code':1, 'site': 'www.runoob.com'}

(2)python中的可变类型和不可变类型:

不可变类型 可变类型
Number(数字) List(列表)
String(字符串) Dic(字典)
Tuple(元组) Sets(集合)

 注: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.一个经典错误

 注:当对象初始化且没有赋值testlist时,会在内存中创建一个空list,如果还有对象没有创建testlist依旧会使用这个空的list的地址,当添加元素或减少元素,所有对象都会改变

 1 class Test:
 2     def __init__(self, name, testlist=[]):
 3         self.name = name
 4         self.testlist = testlist
 5 
 6     def add(self, test):
 7         self.testlist.append(test)
 8 
 9     def remove(self, test):
10         self.testlist.remove(test)
11 
12 
13 test1 = Test("test1")
14 test1.add("test1_add1")
15 
16 test2 = Test("test2")
17 test2.add("test2.add1")
18 
19 print(test1.testlist)   # ['test1_add1', 'test2.add1']
20 print(test2.testlist)   # ['test1_add1', 'test2.add1']
21 
22 test2.remove("test2.add1")
23 print(test1.testlist)   # ['test1_add1']
24 print(test2.testlist)   # ['test1_add1']

 

你可能感兴趣的:(第七章python对象引用、可变性和垃圾回收)