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

    文章

    2767

    浏览量

    72756
  • python
    +关注

    关注

    51

    文章

    4675

    浏览量

    83466
收藏 人收藏

    评论

    相关推荐

    javascript的内置对象有哪些

    JavaScript是一门广泛应用于Web开发的脚本语言,它有很多内置对象,用于处理不同的数据类型、执行不同的操作和提供各种功能。在这篇文章中,我将详尽介绍JavaScript的内置对象
    的头像 发表于 12-03 11:39 757次阅读

    不属于python内置函数

    Python是一种高级编程语言,它提供了许多内置函数,可以帮助开发人员更轻松地处理各种任务。但是,在Python中并非所有的函数都是内置函数。以下是一些不属于
    的头像 发表于 11-29 14:27 534次阅读

    python如何导入模块

    中。本文将详细介绍Python中模块导入的相关知识,并举例演示常见的导入方式和用法。 首先,我们需要明确一些基本的概念。Python 的模块可以分为两种类型:内置模块和第三方模块。内置
    的头像 发表于 11-22 14:46 530次阅读

    Python 不可变对象真的不可变吗

    在日常的学习和工作中,经常会遇到"不可变对象"的问题,但是随着接触Python这门语言的时间越来越多,遇到的坑越来越奇怪。我不禁产生了一个疑问:不可变对象真的不可变吗? 我们知道元组就是"不可变
    的头像 发表于 11-03 11:48 305次阅读
    <b class='flag-5'>Python</b> 不可变<b class='flag-5'>对象</b>真的不可变吗

    Python中元类的作用

    1.什么是类 在理解元类之前,我们必须先掌握Python中的类(class)。 和大多数语言一样,Python中的类知识用来描述如何“生成一个对象”: 但是,在Python中,类不仅能
    的头像 发表于 11-02 11:18 233次阅读
    <b class='flag-5'>Python</b>中元类的作用

    Python 如何判断字符串是否包含子串

    1、使用 in 和 not in in 和 not in 在 Python 中是很常用的关键字,我们将它们归类为 成员运算符 。 使用这两个成员运算符,可以很让我们很直观清晰的判断一个对象
    的头像 发表于 11-02 10:55 252次阅读

    如何用Python转移文件至云对象存储

    对象存储(Cloud Object Storage,COS)是一种存储海量文件的分布式存储服务,具有高扩展性、低成本、可靠安全等优点。 对象存储有什么用呢?对于站长而言,比如Python实用宝典网站
    的头像 发表于 10-31 10:22 286次阅读
    如何用<b class='flag-5'>Python</b>转移文件至云<b class='flag-5'>对象</b>存储

    zip():Python 中最好用的内置类型之一

    zip() 是 Python 中最好用的内置类型之一,它可以接收多个可迭代对象参数,再返回一个迭代器,可以把不同可迭代对象的元素组合起来。 我之前写迭代器系列的时候,在《
    的头像 发表于 10-30 14:21 3087次阅读
    zip():<b class='flag-5'>Python</b> 中最好用的<b class='flag-5'>内置</b>类型之一

    Ruby 与 Python之间的差异

    Ruby 与 Python 之间的差异在很大程度上可通过 for 循环看出本质。 Python 拥有 for 语句。对象告诉 for 如何进行协作,而 for 的循环体会处理对象返回的
    的头像 发表于 10-30 11:50 334次阅读

    Python的面向对象编程详解

    一般编程可分为面向过程编程,和面向对象编程。Python的面向对象编程,与Java的面向对象很像。之所以需要面向对象编程,是为了更好地实现封
    发表于 09-04 16:35 268次阅读
    <b class='flag-5'>Python</b>的面向<b class='flag-5'>对象</b>编程详解

    Python2与Python3中对字符串的支持

    其实Python3中对字符串支持的改进,不仅仅是更改了默认编码,而是重新进行了字符串的实现,而且它已经实现了对UNICODE的内置支持,从这方面来讲Python已经和JAVA一样优秀。下面我们来看
    的头像 发表于 07-05 16:15 525次阅读

    使用Teachable Machine和Python轻松进行对象检测

    电子发烧友网站提供《使用Teachable Machine和Python轻松进行对象检测.zip》资料免费下载
    发表于 06-27 09:26 0次下载
    使用Teachable Machine和<b class='flag-5'>Python</b>轻松进行<b class='flag-5'>对象</b>检测

    python创建文件对象

    2.1. 创建文件对象 **open() 函数用于创建文件对象,基本语法格式如下:** open(文件名[,打开方式]) 注意: 如果只是文件名,代表在当前目录下的文件. 文件名可以录入全路径,比如
    的头像 发表于 06-21 17:19 1069次阅读
    <b class='flag-5'>python</b>创建文件<b class='flag-5'>对象</b>

    Python面向对象深化(下)

    __call__  方法和可调用对象 凡是可以将 () 直接应用到自身并执行, 都称为可调用对象. 注意: 可调用对象包括自定义的函数、Python
    的头像 发表于 05-11 17:52 468次阅读

    Python面向对象深化(上)

    前言 哈喽, 大家好, 我是了不起! 欢迎大家来观看了不起的冒险之旅. 为了方便起见, 文中以小知为名. 讲述了不起在Python异世界的冒险之旅. 天空之城是座高耸云端的城堡. 位于西海岸附近
    的头像 发表于 05-11 17:51 402次阅读
    <b class='flag-5'>Python</b>面向<b class='flag-5'>对象</b>深化(上)