Python对象引用、可变性和垃圾回收

2024-05-02 16:38

本文主要是介绍Python对象引用、可变性和垃圾回收,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

一、Python中的变量是什么

 二、==和is的区别

三、del语句和垃圾回收

四、函数的参数作为引用时

2、不要使用可变类型作为参数的默认值


一、Python中的变量是什么

Python和java中的变量本质不一样。java中的变量是一个盒子,声明时已经说明了盒子的类型,大小。Python的变量实质是一个指针。也可以理解成一个便利贴。可以贴在任何类型上面。

>>> a = [1, 2, 3]
>>> b = a
>>> a.append(4) #操作a实际上也就是操作b
>>> b
[1, 2, 3, 4]

 如果把变量想象为盒子, 那么无法解释 Python 中的赋值;应该把变量视作便利贴, 这样就好解释了。先 生成变量,才把便利贴贴上。


为了理解Python中的赋值语句,应该始终先读右边,对象在右边创建或获取,在此之后左边的变量才会绑定到对象上,这就像为对象贴上标注。

 二、==和is的区别

== 运算符比较两个对象的值(对象中保存的数据) , 而 is 比较对象的标识。

a = [1,2,3]
b = a
print (id(a), id(b))
print (a is b)


通常, 我们关注的是值, 而不是标识, 因此 Python 代码中 == 出现的频率比 is 高。然而, 在变量和单例值之间比较时, 应该使用 is。
 

class People:passperson = People()
if type(person) is People:print ("yes")

 

is 运算符比 == 速度快, 因为它不能重载, 所以 Python 不用寻找并调用特殊方法, 而是直接比较两个整数 ID。 而 a == b 是语法糖, 等同于a.__eq__(b)。
 

三、del语句和垃圾回收

del 语句删除名称, 而不是对象。 del 命令可能会导致对象被当作垃圾回收, 但是仅当删除的变量保存的是对象的最后一个引用, 或者无法得到对象时重新绑定也可能会导致对象的引用数量归零, 导致对象被销毁。

如果两个对象相互引用, 当它们的引用只存在二者之间时, 垃圾回收程序会判定它们都无法获取, 进而把它们都销毁。
 

在 CPython 中, 垃圾回收使用的主要算法是引用计数。 实际上, 每个对象都会统计有多少引用指向自己。 当引用计数归零时, 对象立即就被销毁: CPython 会在对象上调用 __del__ 方法(如果定义了) , 然后释放分配给对象的内存。 CPython 2.0 增加了分代垃圾回收算法。
 

a = object()
b = a
del a
print(b)
print(a)  #无法输出a对象

四、函数的参数作为引用时

  1. Python 唯一支持的参数传递模式是共享传参(call by sharing) 。 多数面向对象语言都采用这一模式, 包括 Ruby、 Smalltalk 和 Java(Java 的引用类型是这样, 基本类型按值传参) 。
  2. 共享传参指函数的各个形式参数获得实参中各个引用的副本。 也就是说, 函数内部的形参是实参的别名。
  3. 这种方案的结果是, 函数可能会修改作为参数传入的可变对象, 但是无法修改那些对象的标识(即不能把一个对象替换成另一个对象) 。
     
>>> def f(a, b):
... a += b
... return a
...
>>> x = 1
>>> y = 2
>>> f(x, y)
3
>>> x, y 
(1, 2)
>>> a = [1, 2] #可变对象
>>> b = [3, 4]
>>> f(a, b)
[1, 2, 3, 4]
>>> a, b 
([1, 2, 3, 4], [3, 4])
>>> t = (10, 20)
>>> u = (30, 40)
>>> f(t, u)
(10, 20, 30, 40)
>>> t, u 
((10, 20), (30, 40))

2、不要使用可变类型作为参数的默认值

可选参数可以有默认值, 这是 Python 函数定义的一个很棒的特性, 这样我们的 API 在进化的同时能保证向后兼容。 然而, 我们应该避免使用可变的对象作为参数的默认值。

class Company:def __init__(self, name, staffs=[]):self.name = nameself.staffs = staffsdef add(self, staff_name):self.staffs.append(staff_name)def remove(self, staff_name):self.staffs.remove(staff_name)if __name__ == "__main__":com1 = Company("com1", ["tian1", "tian2"])com1.add("tian3")com1.remove("tian1")# print (com1.staffs)com2 = Company("com2")com2.add("tian")# print(com2.staffs)#print (Company.__init__.__defaults__) #(['tian'],)#com3 = Company("com3")com3.add("tian5")print (com2.staffs) #['tian', 'tian5']print (com3.staffs) #['tian', 'tian5']print (com2.staffs is com3.staffs)  #True 问题在于, 没有指定初始员工的 Company实例会共 #享同一个乘客列表# #com2和com3共用一个默认的空list

 

这篇关于Python对象引用、可变性和垃圾回收的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/954698

相关文章

Java对象和JSON字符串之间的转换方法(全网最清晰)

《Java对象和JSON字符串之间的转换方法(全网最清晰)》:本文主要介绍如何在Java中使用Jackson库将对象转换为JSON字符串,并提供了一个简单的工具类示例,该工具类支持基本的转换功能,... 目录前言1. 引入 Jackson 依赖2. 创建 jsON 工具类3. 使用示例转换 Java 对象为

使用Python创建一个能够筛选文件的PDF合并工具

《使用Python创建一个能够筛选文件的PDF合并工具》这篇文章主要为大家详细介绍了如何使用Python创建一个能够筛选文件的PDF合并工具,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下... 目录背景主要功能全部代码代码解析1. 初始化 wx.Frame 窗口2. 创建工具栏3. 创建布局和界面控件4

一文详解如何在Python中使用Requests库

《一文详解如何在Python中使用Requests库》:本文主要介绍如何在Python中使用Requests库的相关资料,Requests库是Python中常用的第三方库,用于简化HTTP请求的发... 目录前言1. 安装Requests库2. 发起GET请求3. 发送带有查询参数的GET请求4. 发起PO

Python与DeepSeek的深度融合实战

《Python与DeepSeek的深度融合实战》Python作为最受欢迎的编程语言之一,以其简洁易读的语法、丰富的库和广泛的应用场景,成为了无数开发者的首选,而DeepSeek,作为人工智能领域的新星... 目录一、python与DeepSeek的结合优势二、模型训练1. 数据准备2. 模型架构与参数设置3

Python进行PDF文件拆分的示例详解

《Python进行PDF文件拆分的示例详解》在日常生活中,我们常常会遇到大型的PDF文件,难以发送,将PDF拆分成多个小文件是一个实用的解决方案,下面我们就来看看如何使用Python实现PDF文件拆分... 目录使用工具将PDF按页数拆分将PDF的每一页拆分为单独的文件将PDF按指定页数拆分根据页码范围拆分

Python中常用的四种取整方式分享

《Python中常用的四种取整方式分享》在数据处理和数值计算中,取整操作是非常常见的需求,Python提供了多种取整方式,本文为大家整理了四种常用的方法,希望对大家有所帮助... 目录引言向零取整(Truncate)向下取整(Floor)向上取整(Ceil)四舍五入(Round)四种取整方式的对比综合示例应

python 3.8 的anaconda下载方法

《python3.8的anaconda下载方法》本文详细介绍了如何下载和安装带有Python3.8的Anaconda发行版,包括Anaconda简介、下载步骤、安装指南以及验证安装结果,此外,还介... 目录python3.8 版本的 Anaconda 下载与安装指南一、Anaconda 简介二、下载 An

Python自动化处理手机验证码

《Python自动化处理手机验证码》手机验证码是一种常见的身份验证手段,广泛应用于用户注册、登录、交易确认等场景,下面我们来看看如何使用Python自动化处理手机验证码吧... 目录一、获取手机验证码1.1 通过短信接收验证码1.2 使用第三方短信接收服务1.3 使用ADB读取手机短信1.4 通过API获取

python安装whl包并解决依赖关系的实现

《python安装whl包并解决依赖关系的实现》本文主要介绍了python安装whl包并解决依赖关系的实现,文中通过图文示例介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录一、什么是whl文件?二、我们为什么需要使用whl文件来安装python库?三、我们应该去哪儿下

Python脚本实现图片文件批量命名

《Python脚本实现图片文件批量命名》这篇文章主要为大家详细介绍了一个用python第三方库pillow写的批量处理图片命名的脚本,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下... 目录前言源码批量处理图片尺寸脚本源码GUI界面源码打包成.exe可执行文件前言本文介绍一个用python第三方库pi