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. fluent中截取任意面的数据

    原版视频下载链接: https://pan.baidu.com/s/1c2aE740 密码: mf2i

  2. mysql group by 报错 ,only_full_group_by 三种解决方案

    报错信息  Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'data ...

  3. エンジニア死滅シタ世界之高層ビル [MISSION LEVEL: B]-Python3

    n = input() pre="" next_str = "" new_str = "" for i in range(int(n)): ...

  4. oralce 超过1亿条数据的数据库表清理实践

    2018-08-18 16:58 无腿鸟 阅读(331) 评论(0) 编辑 收藏 问题:当一个表的数据量超过一亿条,要删除其中的5000w条,如何处理. 如果直接使用delete语句,会涉及到到大量的 ...

  5. 【Tomcat】本地域名访问配置

    原路径:localhost:8080/jsja 1.把8080端口改为80端口 打开%TOMCAT_HOME%/conf/server.xml <Connector connectionTime ...

  6. UML建模——活动图(Activity Diagram)

    活动图概述 •活动图和交互图是UML中对系统动态方面建模的两种主要形式 •交互图强调的是对象到对象的控制流,而活动图则强调的是从活动到活动的控制流 •活动图是一种表述过程基理.业务过程以及工作流的技术 ...

  7. Error-JavaScript-SCRIPT5007: 无法获取未定义或 null 引用的属性“style”

    ylbtech-Error-JavaScript-SCRIPT5007: 无法获取未定义或 null 引用的属性“style” 1.返回顶部 - document.getElementById(&qu ...

  8. ISO/IEC 9899:2011 条款6.7.8——类型定义

    6.7.8 类型定义 语法 1.typedef-name: identifier 约束 2.一个typedef名指定了一个可变修改的类型,然后它应该具有语句块作用域. 语义 3.在一个声明中,该声明的 ...

  9. sql 中 '' 与 null 的区别

    SELECT * from t_company where content = '' SELECT * from t_company where content is null update t_co ...

  10. 查看所使用的Linux系统是32位还是64 位的方法

    方法一:getconf LONG_BIT # getconf LONG_BIT 1 1 我的Linux是32位!!! 方法二:arch # arch 1 1 显示 i686 就是32位,显示 x86_ ...