热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

python中的引用计数_内存中的Python:Python引用计数指南阿里云开发者社区

云栖号资讯:【点击查看更多行业资讯】在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来!本文将会为你介绍Pytho

云栖号资讯:【点击查看更多行业资讯】

在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来!

本文将会为你介绍Python引用计数,演示中使用可变列表对象,不过本文不介绍C语言实现细节。

需要注意的是,代码段的输出在硬件上可能有所不同。

变量是内存引用

Python中的变量是内存引用。如果输入x = [1,2]时会发生什么?[1,2]是对象。

回想一下,一切都是Python中的对象。[1,2]将在内存中创建。x是[1,2]对象的内存引用。

来看看下面的例子。可以找到x所引用的内存地址。请务必只使用id(x),它会以10为基数,而十六进制函数会将其转换为十六进制。

x = [1, 2]

print(hex(id(x))) # output: 0x32ebea8

引用计数

现在已经在内存中创建了一个list对象,而且x对该对象进行了引用。那么y=[1,2]和y=x有什么区别?

当输入y=[1,2]时,它将在内存中创建一个新的list对象,并且y将引用它。

x = [1, 2]

y = [1, 2]

print(hex(id(x))) # output: 0x101bea8

print(hex(id(y))) # output: 0x31a5528

而当输入y=x时,等同于告诉Python希望y 变量引用x变量引用的内容。因为变量是内存引用的。

可以确认x和y引用同一个对象。

x = [1, 2]

y = x

print(hex(id(x))) # output: 0x74bea8

print(hex(id(y))) # output: 0x74bea8

引用计数的数目

接下来的问题是,有多少变量引用同一个对象?

错误的用法:

我看到有些人在使用sys.getrefcount(var)时不知道如何传递var,而是向对象添加引用。一起看看下面的例子。

输出3,而期望的却是2(x andy)。发生这种情况是因为将x传递给getrefcount函数时又添加了一个引用。

from sys import getrefcount

x = [1, 2]

y = x

print(hex(id(x))) # output: 0xb65748

print(hex(id(y))) # output: 0xb65748

print(getrefcount(x)) # output: 3

更好的用法:

可以使用内置的ctypes模块来找到预期的结果。必须将x的id传递给from_address函数。

from ctypes import c_long

x = [1, 2]

y = x

print(hex(id(x))) # output: 0x3395748

print(hex(id(y))) # output: 0x3395748

print(c_long.from_address(id(x)).value) # output: 2

概言之,错误的用法是传递变量,而更好的用法则是传递变量的id,这意味着只传递基数为10的数字,而不是变量。

当对象消失时

当没有变量引用对象时会发生什么?

对象将从内存中删除,因为没有引用该对象的内容。不过也有例外:如果有循环引用,garbage collector 将开始奏效。

为什么使用可变对象

不可变对象由于性能原因,结果可能与预期不同。查看下面的例子,观察输出是如何变化的。

import sys

import ctypes

"""Some Mutable Objects """

a =list()

b =set()

c =dict()

d =bytearray()

""" Some ImmutableObjects """

e =tuple()

f =int()

g =str()

print(sys.getrefcount(a),ctypes.c_long.from_address(id(a)).value) # output: 2 1

print(sys.getrefcount(b),ctypes.c_long.from_address(id(b)).value) # output: 2 1

print(sys.getrefcount(c),ctypes.c_long.from_address(id(c)).value) # output: 2 1

print(sys.getrefcount(d),ctypes.c_long.from_address(id(d)).value) # output: 2 1

print(sys.getrefcount(e),ctypes.c_long.from_address(id(e)).value) # output: 1298 1297

print(sys.getrefcount(f),ctypes.c_long.from_address(id(f)).value) # output: 209 208

print(sys.getrefcount(g),ctypes.c_long.from_address(id(g)).value) # output: 59 58

文中所谈及的一切都对CPython有效。希望对你有帮助。

【云栖号在线课堂】每天都有产品技术专家分享!

课程地址:https://yqh.aliyun.com/live

立即加入社群,与专家面对面,及时了解课程最新动态!

【云栖号在线课堂 社群】https://c.tb.cn/F3.Z8gvnK

原文发布时间:2020-05-31

本文作者:读芯术

本文来自:“读芯术”,了解相关信息可以关注“读芯术”



推荐阅读
  • 本文介绍了如何利用ObjectMapper实现JSON与JavaBean之间的高效转换。ObjectMapper是Jackson库的核心组件,能够便捷地将Java对象序列化为JSON格式,并支持从JSON、XML以及文件等多种数据源反序列化为Java对象。此外,还探讨了在实际应用中如何优化转换性能,以提升系统整体效率。 ... [详细]
  • 大类|电阻器_使用Requests、Etree、BeautifulSoup、Pandas和Path库进行数据抓取与处理 | 将指定区域内容保存为HTML和Excel格式
    大类|电阻器_使用Requests、Etree、BeautifulSoup、Pandas和Path库进行数据抓取与处理 | 将指定区域内容保存为HTML和Excel格式 ... [详细]
  • DAO(Data Access Object)模式是一种用于抽象和封装所有对数据库或其他持久化机制访问的方法,它通过提供一个统一的接口来隐藏底层数据访问的复杂性。 ... [详细]
  • 本文介绍了在 Java 编程中遇到的一个常见错误:对象无法转换为 long 类型,并提供了详细的解决方案。 ... [详细]
  • 第二十五天接口、多态
    1.java是面向对象的语言。设计模式:接口接口类是从java里衍生出来的,不是python原生支持的主要用于继承里多继承抽象类是python原生支持的主要用于继承里的单继承但是接 ... [详细]
  • MySQL Decimal 类型的最大值解析及其在数据处理中的应用艺术
    在关系型数据库中,表的设计与SQL语句的编写对性能的影响至关重要,甚至可占到90%以上。本文将重点探讨MySQL中Decimal类型的最大值及其在数据处理中的应用技巧,通过实例分析和优化建议,帮助读者深入理解并掌握这一重要知识点。 ... [详细]
  • 本项目通过Python编程实现了一个简单的汇率转换器v1.02。主要内容包括:1. Python的基本语法元素:(1)缩进:用于表示代码的层次结构,是Python中定义程序框架的唯一方式;(2)注释:提供开发者说明信息,不参与实际运行,通常每个代码块添加一个注释;(3)常量和变量:用于存储和操作数据,是程序执行过程中的重要组成部分。此外,项目还涉及了函数定义、用户输入处理和异常捕获等高级特性,以确保程序的健壮性和易用性。 ... [详细]
  • 属性类 `Properties` 是 `Hashtable` 类的子类,用于存储键值对形式的数据。该类在 Java 中广泛应用于配置文件的读取与写入,支持字符串类型的键和值。通过 `Properties` 类,开发者可以方便地进行配置信息的管理,确保应用程序的灵活性和可维护性。此外,`Properties` 类还提供了加载和保存属性文件的方法,使其在实际开发中具有较高的实用价值。 ... [详细]
  • Python 程序转换为 EXE 文件:详细解析 .py 脚本打包成独立可执行文件的方法与技巧
    在开发了几个简单的爬虫 Python 程序后,我决定将其封装成独立的可执行文件以便于分发和使用。为了实现这一目标,首先需要解决的是如何将 Python 脚本转换为 EXE 文件。在这个过程中,我选择了 Qt 作为 GUI 框架,因为之前对此并不熟悉,希望通过这个项目进一步学习和掌握 Qt 的基本用法。本文将详细介绍从 .py 脚本到 EXE 文件的整个过程,包括所需工具、具体步骤以及常见问题的解决方案。 ... [详细]
  • 原文网址:https:www.cnblogs.comysoceanp7476379.html目录1、AOP什么?2、需求3、解决办法1:使用静态代理4 ... [详细]
  • 如何在Java中使用DButils类
    这期内容当中小编将会给大家带来有关如何在Java中使用DButils类,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。D ... [详细]
  • 本文深入探讨了MDK链接脚本的应用与优化技巧。首先,文章介绍了链接脚本的基本概念及其在嵌入式系统开发中的重要性。接着,通过具体实例详细分析了链接脚本的结构和功能,特别是在程序在FLASH中运行时,如何优化链接脚本以提高系统性能。此外,文章还讨论了无需将程序加载到SRAM中的技术细节,为开发者提供了实用的参考和指导。 ... [详细]
  • 本指南介绍了如何在ASP.NET Web应用程序中利用C#和JavaScript实现基于指纹识别的登录系统。通过集成指纹识别技术,用户无需输入传统的登录ID即可完成身份验证,从而提升用户体验和安全性。我们将详细探讨如何配置和部署这一功能,确保系统的稳定性和可靠性。 ... [详细]
  • 在使用 Qt 进行 YUV420 图像渲染时,由于 Qt 本身不支持直接绘制 YUV 数据,因此需要借助 QOpenGLWidget 和 OpenGL 技术来实现。通过继承 QOpenGLWidget 类并重写其绘图方法,可以利用 GPU 的高效渲染能力,实现高质量的 YUV420 图像显示。此外,这种方法还能显著提高图像处理的性能和流畅性。 ... [详细]
  • 本文介绍了如何利用 Delphi 中的 IdTCPServer 和 IdTCPClient 控件实现高效的文件传输。这些控件在默认情况下采用阻塞模式,并且服务器端已经集成了多线程处理,能够支持任意大小的文件传输,无需担心数据包大小的限制。与传统的 ClientSocket 相比,Indy 控件提供了更为简洁和可靠的解决方案,特别适用于开发高性能的网络文件传输应用程序。 ... [详细]
author-avatar
无聊人生918_644
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有