深浅拷贝

先问问大家,什么是拷贝?拷贝是音译的词,其实他是从copy这个英文单词音译过来的,那什么是copy? copy其实就是复制一份,也就是所谓的抄一份。深浅copy其实就是完全复制一份,和部分复制一份的意思。

先看赋值运算

l1 = [1,2,3,['jason','egon']]
l2 = l1 l1[0] = 111
print(l1) # [111, 2, 3, ['jason', 'egon']]
print(l2) # [111, 2, 3, ['jason', 'egon']] l1[3][0] = 'kevin'
print(l1) # [111, 2, 3, ['kevin', 'egon']]
print(l2) # [111, 2, 3, ['kevin', 'egon']]

对于赋值运算来说,l1与l2指向的是同一个内存地址,所以他们是完全一样的,在举个例子,比如张三李四合租在一起,那么对于客厅来说,他们是公用的,张三可以用,李四也可以用,但是突然有一天张三把客厅的的电视换成投影了,那么李四使用客厅时,想看电视没有了,而是投影了,对吧?l1,l2指向的是同一个列表,任何一个变量对列表进行改变,剩下那个变量在使用列表之后,这个列表就是发生改变之后的列表

浅拷贝copy

#同一代码块下:
l1 = [1, 'jason', True, (1,2,3), [22, 33]]
l2 = l1.copy()
print(id(l1), id(l2)) # 2713214468360 2713214524680
print(id(l1[-2]), id(l2[-2])) # 2547618888008 2547618888008
print(id(l1[-1]),id(l2[-1])) # 2547620322952 2547620322952 # 不同代码块下:
>>> l1 = [1, 'jason', True, (1, 2, 3), [22, 33]]
>>> l2 = l1.copy()
>>> print(id(l1), id(l2))
1477183162696
>>> print(id(l1[-2]), id(l2[-2]))
1477181814032
>>> print(id(l1[-1]), id(l2[-1]))
1477183162504

对于浅copy来说,只是在内存中重新创建了开辟了一个空间存放一个新列表,但是新列表中的元素与原列表中的元素是公用的

深拷贝deepcopy

# 同一代码块下
import copy
l1 = [1, 'jason', True, (1,2,3), [22, 33]]
l2 = copy.deepcopy(l1)
print(id(l1), id(l2)) # 2788324482440 2788324483016
print(id(l1[0]),id(l2[0])) # 1470562768 1470562768
print(id(l1[-1]),id(l2[-1])) # 2788324482632 2788324482696
print(id(l1[-2]),id(l2[-2])) # 2788323047752 2788323047752 # 不同代码块下
>>> import copy
>>> l1 = [1, 'jason', True, (1, 2, 3), [22, 33]]
>>> l2 = copy.deepcopy(l1)
>>> print(id(l1), id(l2))
1477183162632
>>> print(id(0), id(0))
1470562736
>>> print(id(-2), id(-2))
1470562672
>>> print(id(l1[-1]), id(l2[-1]))
1477183162312


对于深copy来说,列表是在内存中重新创建的,列表中可变的数据类型是重新创建的,列表中的不可变的数据类型是公用的

相关面试题

l1 = [1, 2, 3, 4, ['jason']]
l2 = l1[::]
l1[-1].append(666)
print(l2)

python内存泄露

起因

内存泄露指由于疏忽或错误造成程序未能释放已经不再使用的内存的情况。内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,失去了对该段内存的控制,因而造成了内存的浪费。导致程序运行速度减慢甚至系统崩溃等严重后果。有 del() 函数的对象间的循环引用是导致内存泄漏的主凶

方案

不使用一个对象时使用:delobject 来删除一个对象的引用计数就可以有效防止内存泄漏问题。通过Python 扩展模块 gc 来查看不能回收的对象的详细信息。可以通过 sys.getrefcount(obj) 来获取对象的引用计数,并根据返回值是否为 0 来判断是否内存泄漏。
但是由于gc垃圾收集机制,要遍历所有被垃圾收集器管理的python对象(包括垃圾和非垃圾对象),该过程比较耗时可能会造成程序卡顿,会对某些对内存、cpu要求较高的场景造成性能影响。那怎么才能优雅地避免内存泄露呢?

编写安全的代码

比如对于下面发生内存泄露的cycle_ref函数,在函数结束前解除循环引用,即可解决内存泄露问题。

def cycle_ref():
a1 = A()
a2 = A() a1.child = a2
a2.child = a1 # 解除循环引用,避免内存泄露
a1.child = None
a2.child = None

但是对于上述方法,我们有可能会忘记那一两行无关紧要的代码而造成灾难性后果,毕竟老虎也有打盹的时候。那怎么办?不要着急,Python已经为我们考虑到这点:弱引用。

弱引用

Python标准库提供了weakref模块,弱引用不会在引用计数中计数,其主要目的是解决循环引用。并非所有的对象都支持weakref,例如list和dict就不支持。下面是weakref比较常用的方法:

"""
1. class weakref.ref(object[, callback]) :创建一个弱引用对象,object是被引用的对象,callback是回调函数(当被引用对象被删除时,调用该回调函数) 2.weakref.proxy(object[, callback]):创建一个用弱引用实现的代理对象,参数同上 3.weakref.getweakrefcount(object) :获取对象object关联的弱引用对象数 4.weakref.getweakrefs(object):获取object关联的弱引用对象列表 5.class weakref.WeakKeyDictionary([dict]):创建key为弱引用对象的字典 6.class weakref.WeakValueDictionary([dict]):创建value为弱引用对象的字典 7.class weakref.WeakSet([elements]):创建成员为弱引用对象的集合对象
"""

同样对于上面发生内存泄露的cycle_ref函数,使用weakref稍加改造,便可更安全地解决内存泄露问题:

import weakref

class A(object):
def __init__(self):
self.data = [x for x in range(100000)]
self.child = None def __del__(self):
pass def cycle_ref():
a1 = A()
a2 = A() a1.child = weakref.proxy(a2)
a2.child = weakref.proxy(a1) if __name__ == '__main__':
import time
while True:
time.sleep(0.5)
cycle_ref()

你并不了解的format、decimal

谈到format的用法,大家肯定会说不就是用来处理字符串拼接的嘛,谈到decimal你能说出这句话我只能说小伙子你还太嫩了呦~~~让我来装个X天秀一波

format格式化数字



decimal精确处理数字

Python基础——深浅拷贝、python内存泄露、你并不了解的format、decimal的更多相关文章

  1. python基础--深浅拷贝copy

    拷贝是音译的词,其实他是从copy这个英文单词音译过来的,那什么是copy? copy其实就是复制一份,也就是所谓的抄一份.深浅copy其实就是完全复制一份,和部分复制一份的意思. 1.赋值运算 l1 ...

  2. python基础-深浅拷贝

    深拷贝与浅拷贝 总结: # 浅拷贝:list dict: 嵌套的可变数据类型是同一个 # 深拷贝:list dict: 嵌套的不可变数据类型彼此独立 浅拷贝 # 个人理解: # 在内存中重新创建一个空 ...

  3. Python原理 -- 深浅拷贝

    python原理 -- 深浅拷贝 从数据类型说开去 str, num : 一次性创建, 不能被修改, 修改即是再创建. list,tuple,dict,set : 链表,当前元素记录, 下一个元素的位 ...

  4. Python的深浅拷贝

    Python的深浅拷贝 深浅拷贝 1. 赋值,对于list, set, dict来说, 直接赋值. 其实是把内存地址交给变量并不是复制一份内容 list1 = [']] list2 = list1 p ...

  5. 深入理解 Python 的对象拷贝和内存布局

    深入理解 Python 的对象拷贝和内存布局 前言 在本篇文章当中主要给大家介绍 python 当中的拷贝问题,话不多说我们直接看代码,你知道下面一些程序片段的输出结果吗? a = [1, 2, 3, ...

  6. python基础系列教程——Python中的编码问题,中文乱码问题

    python基础系列教程——Python中的编码问题,中文乱码问题 如果不声明编码,则中文会报错,即使是注释也会报错. # -*- coding: UTF-8 -*- 或者 #coding=utf-8 ...

  7. python基础系列教程——Python库的安装与卸载

    python基础系列教程——Python库的安装与卸载 2.1 Python库的安装 window下python2.python3安装包的方法 2.1.1在线安装 安装好python.设置好环境变量后 ...

  8. python基础系列教程——Python的安装与测试:python的IDE工具PyDev和pycharm,anaconda

    ---恢复内容开始--- python基础系列教程——Python的安装与测试:python的IDE工具PyDev和pycharm,anaconda 从头开启python的开发环境搭建.安装比较简单, ...

  9. 深浅拷贝 python

    原文:http://www.jb51.net/article/15714.htm 1. copy.copy 浅拷贝 只拷贝父对象,不会拷贝对象的内部的子对象.2. copy.deepcopy 深拷贝 ...

  10. Python入门-深浅拷贝

    首先我们在这里先补充一下基础数据类型的一些知识: 一.循环删除 1.前面我们学了列表,字典和集合的一些操作方法:增删改查,现在我们来看一下这个问题: 有这样一个列表: lst = ['周杰伦','周润 ...

随机推荐

  1. 驱动开发:内核RIP劫持实现DLL注入

    本章将探索内核级DLL模块注入实现原理,DLL模块注入在应用层中通常会使用CreateRemoteThread直接开启远程线程执行即可,驱动级别的注入有多种实现原理,而其中最简单的一种实现方式则是通过 ...

  2. MVCC并发版本控制之重点ReadView

    MVCC并发版本控制 本文大部分来自<MySQL是怎样运行的>,这里只是简单总结,用于各位回忆和复习. 版本链 对于使用 InnoDB 存储引擎的表来说,它的聚簇索引记录中都包含两个必要的 ...

  3. MyBatis-plus自动填充功能

    1.什么是mp的自动填充?这个功能是做什么的呢? 有的时候,我们可能有这样子的需求,在插入(insert)或者更新数据(update)的时候可以自动填充数据,比如密码,version等.在mp中为我们 ...

  4. OlllyDbg调试器和IDA调试器

    OllyDbg调试器 OllyDbg称为Ring3级的首选工具.可以识别数千个被和Windows频繁使用的函数,并能将其注释出来.它会自动分析函数过程.循环语句等 OllyDbg主界面 快捷键 Add ...

  5. 基于 Spark 的物流企业数据仓库 的设计与实现

    1.设计和实现了一种基于 Spark 的分布式 ETL 系统,包括利用 Spark 抽取.转换清洗和加载数据的具体过程. 2.设计和实现了基于 Spark 的物流企业数据仓库,包括物流企业数据仓库的分 ...

  6. WebSSH之录屏安全审计(三)

    第一篇:Gin+Xterm.js实现WebSSH远程Kubernetes Pod(一) 第二篇:WebSSH远程管理Linux服务器.Web终端窗口自适应(二) 支持用户名密码认证 支持SSH密钥认证 ...

  7. 如何创建Windows 10 虚拟机

    一 ,新建Windows 10 虚拟机 1.1 创建新的虚拟机 1,点击创建新的虚拟机 2,选择典型,点击下一步 3,选择稍后安装操作系统,点击下一步. 4,操作系统选择windwos,版本选着Win ...

  8. 基于md5加密的模拟管理员登录系统

    import os import pandas as pd def md5(string:str=''):     import hashlib     md5 = hashlib.md5()     ...

  9. WPF实现跳动的字符效果

    本文将介绍一个好玩但实际作用可能不太大的动画效果:跳动的字符.为了提高动画效果的可重用性以及调用的灵活性,通过Behavior实现跳动的字符动画.先看下效果: 技术要点与实现 通过TextEffect ...

  10. 手写RISC-V处理器(1)

    由来 由于去年工作变动,有幸进入了芯片行业,但主要工作内容为基于RISC-V的嵌入式应用软件开发,几乎接触不到芯片设计的相关知识,然而随着工作的深入,越来越想探究一下运行在软件之下的CPU的世界,于是 ...