0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

揭秘Python的内置对象

汽车玩家 来源:今日头条 作者:任性的90后boy 2020-01-18 17:30 次阅读

Python 中的sys模块极为基础而重要,它主要提供了一些给解释器使用(或由它维护)的变量,以及一些与解释器强交互的函数。

本文将会频繁地使用该模块的getsizeof()方法,因此,我先简要介绍一下:

该方法用于获取一个对象的字节大小(bytes)

它只计算直接占用的内存,而不计算对象内所引用对象的内存

这里有个直观的例子:

上例说明了一件事:一个静态创建的列表,如果只包含两个元素,那它自身占用的内存就是 80 字节,不管其元素所指向的对象是什么。

好了,拥有这把测量工具,我们就来探究一下 Python 的内置对象都藏了哪些小秘密吧。

1、空对象不是“空”的!

对于我们熟知的一些空对象,例如空字符串、空列表、空字典等等,不知道大家是否曾好奇过,是否曾思考过这些问题:

空的对象是不是不占用内存呢?如果占内存,那占用多少呢?为什么是这样分配的呢?

直接上代码吧,一起来看看几类基本数据结构的空对象的大小:

可见,虽然都是空对象,但是这些对象在内存分配上并不为“空”,而且分配得还挺大(记住这几个数字哦,后面会考)。

排一下序:基础数字<空元组 < 空字符串 < 空列表 < 空集合 < 空字典。

这个小秘密该怎么解释呢?

因为这些空对象都是容器,我们可以抽象地理解:它们的一部分内存用于创建容器的骨架、记录容器的信息(如引用计数、使用量信息等等)、还有一部分内存则是预分配的。

2、内存扩充不是均匀的!

空对象并不为空,一部分原因是 Python 解释器为它们预分配了一些初始空间。在不超出初始内存的情况下,每次新增元素,就使用已有内存,因而避免了再去申请新的内存。

那么,如果初始内存被分配完之后,新的内存是怎么分配的呢?

分别给三类可变对象添加 26 个元素,看看结果如何:

由此能看出可变对象在扩充时的秘密:

超额分配机制:申请新内存时并不是按需分配的,而是多分配一些,因此当再添加少量元素时,不需要马上去申请新内存

非均匀分配机制:三类对象申请新内存的频率是不同的,而同一类对象每次超额分配的内存并不是均匀的,而是逐渐扩大的

3、列表不等于列表!

以上的可变对象在扩充时,有相似的分配机制,在动态扩容时可明显看出效果。

那么,静态创建的对象是否也有这样的分配机制呢?它跟动态扩容比,是否有所区别呢?

先看看集合与字典:

看到这个结果,再对比上一节的截图,可以看出:在元素个数相等时,静态创建的集合/字典所占的内存跟动态扩容时完全一样。

这个结论是否适用于列表对象呢?一起看看:

上一节的截图显示,列表在前 4 个元素时都占 96 字节,在 5 个元素时占 128 字节,与这里明显矛盾。

所以,这个秘密昭然若揭:在元素个数相等时,静态创建的列表所占的内存有可能小于动态扩容时的内存!

也就是说,这两种列表看似相同,实际却不同!列表不等于列表!

4、消减元素并不会释放内存!

前面提到了,扩充可变对象时,可能会申请新的内存。

那么,如果反过来缩减可变对象,减掉一些元素后,新申请的内存是否会自动回收掉呢?

如代码所示,列表在一扩一缩后,虽然回到了原样,但是所占用的内存空间可没有自动释放啊。其它的可变对象同理。

这就是 Python 的小秘密了,“胖子无法减重原理”:瘦子变胖容易,缩减身型也容易,但是体重减不掉,哈哈~~~

5、空字典不等于空字典!

使用 pop() 方法,只会缩减可变对象中的元素,但并不会释放已申请的内存空间。

还有个 clear() 方法,它会清空可变对象的所有元素,让我们试试看吧:

调用 clear() 方法,我们就获得了几个空对象。

在第一小节里,它们的内存大小已经被查验过了。(前面说过会考的,请默写回看下)

但是,如果这时再查验的话,你会惊讶地发现,这些空对象的大小跟前面查的并不完全一样!

空列表与空元组的大小不变,然而空字典(72)竟然比前面的空字典(240)要小很多!

也就是说,列表与元组在清空元素后,回到起点不变初心,然而,字典这家伙却是“赔了夫人又折兵”,不仅把“吃”进去的全吐出来了,还把自己的老本给亏掉了!

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 内存
    +关注

    关注

    8

    文章

    3028

    浏览量

    74098
  • python
    +关注

    关注

    56

    文章

    4797

    浏览量

    84745
收藏 人收藏

    评论

    相关推荐

    揭秘共模电感漏感对使用有影响吗

    电子发烧友网站提供《揭秘共模电感漏感对使用有影响吗.docx》资料免费下载
    发表于 09-30 14:45 1次下载

    LDO噪声揭秘

    电子发烧友网站提供《LDO噪声揭秘.pdf》资料免费下载
    发表于 09-21 09:13 0次下载
    LDO噪声<b class='flag-5'>揭秘</b>

    DM368 NAND Flash启动揭秘

    电子发烧友网站提供《DM368 NAND Flash启动揭秘.pdf》资料免费下载
    发表于 08-27 09:22 0次下载
    DM368 NAND Flash启动<b class='flag-5'>揭秘</b>

    pytorch和python的关系是什么

    在当今的人工智能领域,Python已经成为了最受欢迎的编程语言之一。Python的易学易用、丰富的库和框架以及强大的社区支持,使其成为了数据科学、机器学习和深度学习等领域的首选语言。而在深度学习领域
    的头像 发表于 08-01 15:27 2004次阅读

    Python建模算法与应用

    Python作为一种功能强大、免费、开源且面向对象的编程语言,在科学计算、数学建模、数据分析等领域展现出了卓越的性能。其简洁的语法、对动态输入的支持以及解释性语言的本质,使得Python在多个平台
    的头像 发表于 07-24 10:41 569次阅读

    揭秘中国汽车芯片市场:主要企业有哪些?

    揭秘中国汽车芯片市场:主要企业有哪些?
    的头像 发表于 07-19 10:12 588次阅读
    <b class='flag-5'>揭秘</b>中国汽车芯片市场:主要企业有哪些?

    opencv-python和opencv一样吗

    不一样。OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉和机器学习软件库,它提供了大量的图像和视频处理功能。OpenCV-Python
    的头像 发表于 07-16 10:38 1222次阅读

    python训练出的模型怎么调用

    使用pickle模块 pickle 是Python的一个内置模块,用于序列化和反序列化Python对象结构。使用 pickle 可以方便地保存和加载模型。 import pickle
    的头像 发表于 07-11 10:15 2003次阅读

    EMC大揭秘 PCB设计必备指南

    EMC大揭秘 PCB设计必备指南
    的头像 发表于 06-15 16:29 3090次阅读
    EMC大<b class='flag-5'>揭秘</b> PCB设计必备指南

    华为云开发者桌面全新发布 CodeArts IDE for Python,极致优雅云原生开发体验

    近日,华为云正式发布 CodeArts IDE for Python,这是一款内置华为自研 Python 语言服务,提供智能编程、灵活调试能力的可扩展桌面开发工具,为华为云开发者提供卓越
    的头像 发表于 05-10 00:27 1247次阅读
    华为云开发者桌面全新发布 CodeArts IDE for <b class='flag-5'>Python</b>,极致优雅云原生开发体验

    华为云正式发布CodeArts IDE for Python

    近日,华为云正式发布CodeArts IDE for Python,这是一款内置华为自主创新的Python语言服务,提供智能编程、灵活调试能力的可扩展桌面开发工具,为华为云开发者提供卓越Pyt
    的头像 发表于 05-08 14:58 506次阅读

    如何使用Python生成四位随机数字

    为了实现这些目标,Python 为我们提供了random() 模块。random() 是一个内置Python 模块,用于生成随机数。
    的头像 发表于 04-15 12:47 682次阅读

    揭秘共模电感选择技巧

    电子发烧友网站提供《揭秘共模电感选择技巧.docx》资料免费下载
    发表于 03-29 14:36 0次下载

    医疗新革命,磁传感技术应用细分揭秘

    电子发烧友网站提供《医疗新革命,磁传感技术应用细分揭秘!.pdf》资料免费下载
    发表于 03-05 14:39 4次下载

    python中open函数的用法详解

    python中open函数的用法详解 Python中的open()函数用于打开文件。它接受文件名和模式作为参数,并返回一个文件对象。文件对象可用于读取、写入和管理文件。 open()函
    的头像 发表于 01-30 15:31 2148次阅读