1、标识、相等性和别名

  1. 别名的例子
>>> charles = {'name': 'Charles L. Dodgson', 'born': 1832}
>>> lewis = charles
>>> lewis is charles
True
>>> id(charles)
139996185268800
>>> id(lewis)
139996185268800

  2.相等性的例子

>>> charles = {'name': 'Charles L. Dodgson', 'born': 1832}
>>> alex = {'name': 'Charles L. Dodgson', 'born': 1832}
>>> alex == charles
True
>>> alex is charles
False
>>> id(alex)
139996185193136
>>> id(charles)
139996185268800
备注:== 运算符比较两个对象的值(对象中保存的数据),而 is 比较对象的标识。
is 运算符比 == 速度快,因为它不能重载,所以 Python 不用寻找并调用特殊方法,而是直接比较两个整数 ID。
而 a == b 是语法糖,等同于 a.__eq__(b) 。
 

2、默认做浅复制

复制列表(或多数内置的可变集合)最简单的方式是使用内置的类型构造方法。

>>> l1 = [12,123,22,213,222,1221]
>>> l2 = list(l1)
>>> l2 == l1
True
>>> l2 is l1
False
创建 l1的副本,l2和l1相等,但是l2和l1是不同的对象;也可以这个样复制, l2 = l1[:]
然而,构造方法或 [:] 做的是浅复制(即复制了最外层容器,副本中的元素是源容器中元素的引用)。
如果所有元素都是不可变的,那么这样没有问题,还能节省内存。但是,如果有可变的元素,可能就会导致意想不到的问题。
 
>>> l1 = [3, [66,55,44], (7,8,9)]
>>> l2 = l1[:]
>>> l1.append(100)
>>> l1
[3, [66, 55, 44], (7, 8, 9), 100]
>>> l1[1].remove(55)
>>> print('l1', l1)
l1 [3, [66, 44], (7, 8, 9), 100]
>>> print('l2', l2)
l2 [3, [66, 44], (7, 8, 9)] >>> l2[1] += [33,22]
>>> l2[2] += (10,11)
>>> print('l1', l1)
l1 [3, [66, 44, 33, 22], (7, 8, 9), 100]
>>> print('l2', l2)
l2 [3, [66, 44, 33, 22], (7, 8, 9, 10, 11)] 
解释一下上面发生的现象,l1里面有三个元素, 分别是3,[66,55,44],(7,8,9);l1引用这三个,l2也引用这三个
当l1进行append 时,不会对l2造成影响;但是l1删除55的时候,l1的引用变成了[66,44] 此时l2的引用也变成了这个;
当l2对[66,44] + [33,22]时,l2和l1的引用都会变;但是当l2改变了元组(7,8,9)时,(元组是不可变对象)此时l2引用的元组变了(7,8,9,10,11),但是l1的
引用还是(7,8,9)
 

3、深复制

浅复制没什么问题,但有时我们需要的是深复制(即副本不共享内部对象的引用)。
 copy模块提供的 deepcopy 和 copy 函数能为任意对象做深复制和浅复制。
import copy

class Bus(object):
def __init__(self, passengers=None):
if passengers is None:
self.passengers = []
if passengers is not None:
self.passengers = list(passengers) def drop(self, name):
self.passengers.remove(name) def pick(self, name):
self.passengers.append(name) bus1 = Bus(['Alice', 'Bill', 'Claire', 'David'])
bus2 = copy.copy(bus1)
bus3 = copy.deepcopy(bus1)
bus1.drop('Bill')
bus1.pick('tom')
print(bus1.passengers)
print(bus2.passengers)
print(bus3.passengers)
# -------------------------
# bus1 ['Alice', 'Claire', 'David', 'tom']
# bus2 ['Alice', 'Claire', 'David', 'tom']
# bus3 ['Alice', 'Bill', 'Claire', 'David']

  浅复制时,bus1和bus2,公用了一个列表对象,这个是可变对象

Python对象的引用、可变性和垃圾回收的更多相关文章

  1. 流畅的python第八章对象引用,可变性和垃圾回收

    变量不是盒子 在==和is之间选择 ==比较两个对象的值,而is比较对象的标识 元组的相对不可变姓 元组与多数的python集合(列表,字典,集,等等)一样,保存的是对象的引用.如果引用的元素是可变的 ...

  2. 流畅的python 对象引用 可变性和垃圾回收

    对象引用.可变性和垃圾回收 变量不是盒子 人们经常使用“变量是盒子”这样的比喻,但是这有碍于理解面向对象语言中的引用式变量.Python 变量类似于 Java 中的引用式变量,因此最好把它们理解为附加 ...

  3. 基于Python对象引用、可变性和垃圾回收详解

    基于Python对象引用.可变性和垃圾回收详解 下面小编就为大家带来一篇基于Python对象引用.可变性和垃圾回收详解.小编觉得挺不错的,现在就分享给大家,也给大家做个参考. 变量不是盒子 在示例所示 ...

  4. PythonI/O进阶学习笔记_6.对象引用,可变性和垃圾回收

    前言: 没有前言了- -......这系列是整理的以前的笔记上传的,有些我自己都忘记我当时记笔记的关联关系了. 记住以后 笔记记了就是用来复习的!!!不看不就啥用没了吗!!! content: 1.p ...

  5. Fluent_Python_Part4面向对象,08-ob-ref,对象引用、可变性和垃圾回收

    第四部分第8章,对象引用.可变性和垃圾回收 1. 创建对象之后才会把变量分配给对象 变量是对象的标注,是对象的别名,是对象的引用,并不是对象存储的地方. 例子1. 证明赋值语句的右边先执行 class ...

  6. Python 对象的引用计数和拷贝

    Python 对象的引用计数和拷贝 Python是一种面向对象的语言,包括变量.函数.类.模块等等一切皆对象. 在python中,每个对象有以下三个属性: 1.id,每个对象都有一个唯一的身份标识自己 ...

  7. Java中的引用类型(强引用、弱引用)和垃圾回收

    Java中的引用类型和垃圾回收 强引用Strong References 强引用是最常见的引用: 比如: StringBuffer buffer = new StringBuffer(); 创建了一个 ...

  8. JVM内存回收区域+对象存活的判断+引用类型+垃圾回收线程

    此文已由作者赵计刚薪授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 注意:本文主要参考自<深入理解Java虚拟机(第二版)> 说明:查看本文之前,推荐先知道JVM ...

  9. 第三章 JVM内存回收区域+对象存活的判断+引用类型+垃圾回收线程

    注意:本文主要参考自<深入理解Java虚拟机(第二版)> 说明:查看本文之前,推荐先知道JVM内存结构,见<第一章 JVM内存结构> 1.内存回收的区域 堆:这是GC的主要区域 ...

  10. netty 引用计数器 ,垃圾回收

    netty 引用计数器 ,垃圾回收 https://blog.csdn.net/u013851082/article/details/72170065 Netty之有效规避内存泄漏 https://w ...

随机推荐

  1. Android根据内网外网连接情况配置服务器访问IP

    新项目的app,可通过内网和外网的服务器ip进行请求访问,但是客户提供了专业终端,终端在wifi情况下走外网内网都可以,但关闭wifi则只能走4G专网,也就是只能走内网. 可前往我的小站查看:Andr ...

  2. css中的浮动与定位

    传送门:https://www.cnblogs.com/junwuyao/p/7435257.html

  3. useState 的介绍和多状态声明(二)

    useState的介绍 useState是react自带的一个hook函数,它的作用是用来声明状态变量. 那我们从三个方面来看useState的用法,分别是声明.读取.使用(修改).这三个方面掌握了, ...

  4. HTMLPage测试js通过ajax调用

    HTMLPage测试js通过ajax调用接口 <!DOCTYPE html> <html lang="en" xmlns="http://www.w3. ...

  5. laravel 通过ftp上传的时候报错 Use of undefined constant FTP_BINARY - assumed 'FTP_BINARY

    用Laravel中的filesystems里面的ftp上传文件时报错.在windows上开发,文件上传的时候碰到上面的问题,搜了些资料,发现是php7的ftp拓展默认未开启. filesystems是 ...

  6. python 设计模式之桥接模式 Bridge Pattern

    #写在前面 前面写了那么设计模式了,有没有觉得有些模式之间很类似,甚至感觉作用重叠了,模式并不是完全隔离和独立的,有的模式内部其实用到了其他模式的技术,但是又有自己的创新点,如果一味地认为每个模式都是 ...

  7. centos7搭建maven私服

    Linux:CentOS7安装maven私服Nexus https://blog.csdn.net/plei_yue/article/details/78616267 搭建nexus3版的maven私 ...

  8. linux内核在挂载ramdisk的过程中报错"RAMDISK: incomplete write (10739 != 32768)"如何处理?

    1. 原因 ramdisk大小不够 2. 解决方法 在启动变量bootargs中添加参数"ramdisk_size=10000000"即可

  9. MySQL there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause同时创建多个更新当前时间戳字段 解决方法

    问题重现 在写这篇文章之前,明确我的MySQL版本,MariaDB 或者你使用 MySQL 8 也会出现如下问题 MySQL 版本 现在有这样的需求,一张表中有一个字段created_at记录创建该条 ...

  10. [转]Winform打包工具SetupFactory 9 的使用

    写了个WinForm的小程序..以前没打过包..只是直接把Bin里的东西复制出来使用..自己使用是足够.但是发给别人毕竟不太好看(不牛逼)..所以就想着打包.. Vs2012自带的有打包的功能..相信 ...