首页 > 编程 > Python > 正文

基于Python对象引用、可变性和垃圾回收详解

2020-02-16 02:07:07
字体:
来源:转载
供稿:网友

变量不是盒子

在示例所示的交互式控制台中,无法使用“变量是盒子”做解释。图说明了在 Python 中为什么不能使用盒子比喻,而便利贴则指出了变量的正确工作方式。

变量 a 和 b 引用同一个列表,而不是那个列表的副本

>>> a = [1, 2, 3]>>> b = a>>> a.append(4)>>> b[1, 2, 3, 4]

如果把变量想象为盒子,那么无法解释 Python 中的赋值;应该把变量视作便利贴,这样示例中的行为就好解释了

注意:

对引用式变量来说,说把变量分配给对象更合理,反过来说就有问题。毕竟,对象在赋值之前就创建了

标识、相等性和别名

Lewis Carroll 是 Charles Lutwidge Dodgson 教授的笔名。Carroll 先生指的就是 Dodgson 教授,二者是同一个人。🌰 用 Python 表达了这个概念。

charles 和 lewis 指代同一个对象

>>> lewis = charles>>> lewis is charlesTrue>>> id(lewis), id(charles)(4303312648, 4303312648)>>> lewis['balance'] = 950>>> charles{'name': 'Charles L. Dodgson', 'born': 1832, 'balance': 950}

然而,假如有冒充者(姑且叫他 Alexander Pedachenko 博士)生于 1832年,声称他是 Charles L. Dodgson。这个冒充者的证件可能一样,但是Pedachenko 博士不是 Dodgson 教授。这种情况如图

charles 和 lewis 绑定同一个对象,alex 绑定另一个具有相同内容的对象

alex 与 charles 比较的结果是相等,但 alex 不是charles

>>> lewis{'name': 'Charles L. Dodgson', 'born': 1832, 'balance': 950}>>> alex = {'name': 'Charles L. Dodgson', 'born': 1832, 'balance': 950}>>> lewis == alexTrue>>> alex is not lewisTrue

alex 指代的对象与赋值给 lewis 的对象内容一样,比较两个对象,结果相等,这是因为 dict 类的 __eq__ 方法就是这样实现的,但它们是不同的对象。这是 Python 说明标识不同的方式:a is notb。

示例体现了别名。在那段代码中,lewis 和 charles 是别名,即两个变量绑定同一个对象。而 alex 不是 charles 的别名,因为二者绑定的是不同的对象。alex 和 charles 绑定的对象具有相同的值(== 比较的就是值),但是它们的标识不同。

在==和is之间选择

== 运算符比较两个对象的值(对象中保存的数据),而 is 比较对象的标识。通常,我们关注的是值,而不是标识,因此 Python 代码中 == 出现的频率比 is 高。然而,在变量和单例值之间比较时,应该使用 is。目前,最常使用 is检查变量绑定的值是不是 None。下面是推荐的写法:

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表