zoukankan      html  css  js  c++  java
  • 第七章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']
  • 相关阅读:
    elementui问题汇总
    微信小程序实现微信授权登录
    微信小程序数据存储
    小程序使用第三方服务,需要中转到一个h5页面,返回到指定页面
    小程序开发,通过左上角返回到指定页面
    万恶之源-基本数据类型(list,tuple)
    基础中的基础
    mybatis_plus实现自动填充和逻辑删除
    本地端口占用解决方案
    maven定义版本以来报红解决方案
  • 原文地址:https://www.cnblogs.com/zhihaospace/p/12089255.html
Copyright © 2011-2022 走看看