python中隐式的内存共享
在python中,基本上使用的是引用,那么就会造成一个隐式的内存共享,特别是在容器对象中,例如list,dictionary
对于不可变对象,是不会造成隐式的内存共享情况,如下所示:
>>> alist = [0]*5
>>> print alist
[0, 0, 0, 0, 0]
>>> alist[0]= 'kel'
>>> alist
['kel', 0, 0, 0, 0]
以上为不可变对象数字类型,数字是不可变对象,在每次都会新建这一对象。
>>> alist = ['kel']*5
>>> alist
['kel', 'kel', 'kel', 'kel', 'kel']
>>> alist[0]='changed'
>>> alist
['changed', 'kel', 'kel', 'kel', 'kel']
字符串也是不可变类型,从而在修改一个对象的时候,其他的对象都会重新建立
在多维数组列表中,则会造成隐式的内存共享,也就是修改其中一个的值其他的值也会发生改变,如下所示:
>>> multi = [[0]*5]*3
>>> multi
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
>>> multi[0][0]='kel'
>>> multi
[['kel', 0, 0, 0, 0], ['kel', 0, 0, 0, 0], ['kel', 0, 0, 0, 0]]
当使用列表解析的时候,会造成隐式内存共享,在每次使用的时候,都是指向同一个对象,具体的如下所示:
>>> row = [0]*5
>>> multi = [row]*3
>>> multi
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
>>> multi[0][0]='kel'
>>> multi
[['kel', 0, 0, 0, 0], ['kel', 0, 0, 0, 0], ['kel', 0, 0, 0, 0]]
1、 row中的五个子项都引用0 -——在这个时候修改其中之一的值,不会影响其他的值,因为是不可变对象
2、multi中的3个子项都引用row——从而在修改最里面的值的时候,都会影响其他的值,因为指向的是同一个对象row
如果对象是不可变的,则对象和对象引用实际上没什么区别。
要解决内存共享的问题,那么可以使用双层循环的列表解析,而不是使用直接使用重复的列表解析:
>>> mmultilist = [[0 for x in range(3)] for x in range(5)]
>>> mmultilist
[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> mmultilist[0][0]='kel'
>>> mmultilist
[['kel', 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
在进行修改的时候,没有影响到其他的值,从而这种方法是可以的。
另外,在使用这种双层循环的方式中,可以对开始的进行简化,从而代码如下:
>>> multilist=[[0]*3 for x in range(5)]
>>> multilist
[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> multilist[0][0] = 'kel'
>>> multilist
[['kel', 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
当直接使用列表乘以整数的时候,可以直接得到列表的重复,注意在这里如果是不可变对象,那么可以使用;如果涉及到了几维数据的话,那么就必须使用其中的循环从而消除对内存共享的影响。
此种问题对于可变对象才会发生,而对于不可变对象是不会发生的。
python中隐式的内存共享的更多相关文章
- python 中的Array,Value及内存共享
官网文档的例子 from multiprocessing import Process, Value, Array def f(n, a): n.value = 3.1415927 for i in ...
- python是如何进行内存管理的
Python引入了一个机制:引用计数. python内部使用引用计数,来保持追踪内存中的对象,Python内部记录了对象有多少个引用,即引用计数,当对象被创建时就创建了一个引用计数,当对象不再需要时, ...
- python面试题之Python是如何进行内存管理的
python内部使用引用计数,来保持追踪内存中的对象,Python内部记录了对象有多少个引用,即引用计数,当对象被创建时就创建了一个引用计数,当对象不再需要时,这个对象的引用计数为0时,它被垃圾回收. ...
- 孤荷凌寒自学python第三十七天python的文件与内存变量之间的序列化与反序列化
孤荷凌寒自学python第三十七天python的文件与内存变量之间的序列化与反序列化 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 一.什么是序列化与反序列化 序列化是指将内存中的数据进行指 ...
- Python是如何进行内存管理
三个方面:一对象的引用计数机制,二垃圾回收机制,三内存池机制 一.对象的引用计数机制 Python内部使用引用计数,来保持追踪内存中的对象,所有对象都有引用计数. 引用计数增加的情况: 1,一个对象分 ...
- python是如何进行内存管理的?
Python内存管理机制 Python内存管理机制主要包括以下三个方面: 引用计数机制 垃圾回收机制 内存池机制 引用计数 举个例子说明引用是什么: 1 如上为一个简单的赋值语句,1就是对象,a就是引 ...
- <Python基础>python是如何进行内存管理的
.Python 是如何进行内存管理的?答:从三个方面来说,一对象的引用计数机制,二垃圾回收机制,三内存池机制⒈对象的引用计数机制Python 内部使用引用计数,来保持追踪内存中的对象,所有对象都有引用 ...
- Python推导式详解,带你写出比较精简酷炫的代码
Python推导式详解,带你写出比较精简酷炫的代码 前言 1.推导式分类与用法 1.1 列表推导 1.2 集合推导 1.3 字典推导 1.4 元组推导?不存在的 2.推导式的性能 2.1 列表推导式与 ...
- Python正则式的基本用法
Python正则式的基本用法 1.1基本规则 1.2重复 1.2.1最小匹配与精确匹配 1.3前向界定与后向界定 1.4组的基本知识 2.re模块的基本函数 2.1使用compile加速 2.2 ma ...
随机推荐
- Netty那点事
一.Netty是什么 Netty,无论新手还是老手,都知道它是一个“网络通讯框架”. 所谓框架,基本上都是一个作用:基于底层API,提供更便捷的编程模型. 那么”通讯框架”到底做了什么事情呢?回答这个 ...
- dojo 总结
对以前项目中用到的dojo框架进行一个框架式的总结,以备参考学习. 主要组成... 1 开发注意... 3 Dojo代码约定... 3 Dojo形式的脚本库... 4 Dojo Build. 4 Do ...
- 使用Gson解析复杂的json数据
Gson解析复杂的json数据 最近在给公司做一个直播APK的项目,主要就是通过解析网络服务器上的json数据,然后将频道地址下载下来再调用Android的播放器进行播放,原先本来打算使用普通的jso ...
- combobox远程加载数据的总结和Json数据的小结
1.从后台返回请求加载Combobox下拉框数据 html部分1 <select name="mateBelongZ" id="mateBelongZID" ...
- non-overlapping-intervals
https://leetcode.com/problems/non-overlapping-intervals/ 其中还用到了Java的Comparator接口和其中的compare方法. packa ...
- typedef struct trx_struct trx_t;
/* The transaction handle; every session has a trx object which is freed only when the session is fr ...
- hdu4605 magic ball game 树状数组+离线处理
题意:给你一棵二叉树,每个节点有一个w值,现在有一颗小球,值为x,从根节点往下掉,如果w==x,那么它就会停止:如果w>x,那么它往左.右儿子的概率都是1.2:如果w<x,那么它往左儿子的 ...
- 漫游Kafka设计篇之消息传输的事务定义
之前讨论了consumer和producer是怎么工作的,现在来讨论一下数据传输方面.数据传输的事务定义通常有以下三种级别: 最多一次: 消息不会被重复发送,最多被传输一次,但也有可能一次不传输. 最 ...
- 作业调度框架 Quartz.NET 2.0 StepByStep
注:目前网上诸多介绍Quartz.net的文章,甚至Quartz.net官网上的Tutorial都是1.0版本的,而这个项目在2.0版本对项目进行了比较大规模的修改,使得原有的很多例子都不能运行,故写 ...
- 代码开光,Orz
有一次在cf上看到了,666,- - // // _oo0oo_ // o8888888o // 88" . "88 // (| -_- |) // 0\ = /0 // ___/ ...