变量不是盒子
在示例所示的交互式控制台中,无法使用“变量是盒子”做解释。图说明了在 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。下面是推荐的写法:
新闻热点
疑难解答