前言

最近看到一个题目,看似很简单,其实里面有很深的意义,题目是Python 表达式 i += x 与 i = i + x 等价吗?如果你的回答是yes,那么恭喜你正确了50%,为什么说只对了一半呢? 按照我们的一般理解它们俩是等价的,整数操作时两者没什么异同,但是对于列表操作,是不是也一样呢?
先看下面两段代码:
代码1
>>> l1 = range(3) >>> l2 = l1 >>> l2 += [3] >>> l1 [0, 1, 2, 3] >>> l2 [0, 1, 2, 3]
代码2
>>> l1 = range(3) >>> l2 = l1 >>> l2 = l2 + [3] >>> l1 [0, 1, 2] >>> l2 [0, 1, 2, 3]
代码1与代码2中的l2的值是一样的,但是l1的值却不一样,说明 i += x 与 i = i + x 是不等价的,那什么情况下等价,什么情况下不等价呢?
弄清楚这个问题之前,首选得明白两个概念:可变对象与不可变对象。
在 Python 中任何对象都有的三个通用属性:唯一标识、类型、值。
唯一标识:用于标识对象的在内存中唯一性,它在对象创建之后就不会再改变,函数 id()可以查看对象的唯一标识
类型:决定了该对象支持哪些操作,不同类型的对象支持的操作就不一样,比如列表可以有length属性,而整数没有。同样地对象的类型一旦确定了就不会再变,函数 type()可以返回对象的类型信息。
对象的值与唯一标识不一样,并不是所有的对象的值都是一成不变的,有些对象的值可以通过某些操作发生改变,值可以变化的对象称之为可变对象(mutable),值不能改变的对象称之为不可变对象(immutable)
不可变对象(immutable)
对于不可变对象,值永远是刚开始创建时候的值,对该对象做的任何操作都会导致一个新的对象的创建。
>>> a = 1 >>> id(a) 32574568 >>> a += 1 >>> id(a) 32574544
整数 “1” 是一个不可变对象,最初赋值的时候,a 指向的是整数对象 1 ,但对变量a执行 += 操作后, a 指向另外一个整数对象 2 ,但对象 1 还是在那里没有发生任何变化,而 变量 a 已经指向了一个新的对象2。常见的不可变对象有:int、tuple、set、str。
可变对象(mutable)
可变对象的值可以通过某些操作动态的改变,比如列表对象,可以通过append方法不断地往列表中添加元素,该列表的值就在不断的处于变化中,一个可变对象赋值给两个变量时,他们共享同一个实例对象,指向相同的内存地址,对其中任何一个变量操作时,同时也会影响另外一个变量。
>>> x = range(3) >>> y = x >>> id(x) 139726103041232 >>> id(y) 139726103041232 >>> x.append(3) >>> x [0, 1, 2, 3] >>> y [0, 1, 2, 3] >>> id(x) 139726103041232 >>> id(y) 139726103041232
执行append操作后,对象的内存地址不会改变,x、y 依然指向的是原来同一个对象,只不过是他的值发生了变化而已。
理解完可变对象与不可变对象后,回到问题本身,+= 与 +的区别在哪里呢?
+= 操作首先会尝试调用对象的 __iadd__方法,如果没有该方法,那么尝试调用__add__方法,先来看看这两个方法有什么区别
__add__和 __iadd__ 的区别
>>> hasattr(int, '__iadd__') False >>> hasattr(list, '__iadd__') True
显然,整数对象是没有__iadd__的,而列表对象提供了__iadd__方法。
>>> l2 += [3] # 代码1:使用__iadd__,l2的值原地修改
代码1中的 += 操作调用的是__iadd__方法,他会原地修改l2指向的那个对象本身的值
>>> l2 = l2 + [3] # 代码2:调用 __add__,创建了一个新的列表,赋值给了l2
而代码2中的 + 操作调用的是 __add__ 方法,该方法会返回一个新的对象,原来的对象保持不变,l1还是指向原来的对象,而l2已经指向一个新的对象。
以上就是表达式 i += x 与 i = i + x 的区别。因此对于列表进行 += 操作时,会存在潜在的bug,因为l1会因为l2的变化而发生改变,就像函数的参数不宜使用可变对象作为关键字参数一样。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。
# python
# 表达式
# x
# 等价于
# 等价表达式
# Python中表达式x += y和x = x+y 的区别详解
# 的是
# 就不
# 可以通过
# 另外一个
# 会再
# 称之为
# 都是
# 是一个
# 情况下
# 就在
# 也会
# 就像
# 第一个
# 在那里
# 这个问题
# 它是
# 这两个
# 他会
# 给了
# 很简单
相关文章:
网站制作报价单模板图片,小松挖机官方网站报价?
C#怎么使用委托和事件 C# delegate与event编程方法
免费公司网站制作软件,如何申请免费主页空间做自己的网站?
公司网站的制作公司,企业网站制作基本流程有哪些?
如何用花生壳三步快速搭建专属网站?
如何通过FTP服务器快速搭建网站?
如何在阿里云ECS服务器部署织梦CMS网站?
SQL查询语句优化的实用方法总结
高配服务器限时抢购:企业级配置与回收服务一站式优惠方案
微信h5制作网站有哪些,免费微信H5页面制作工具?
个人摄影网站制作流程,摄影爱好者都去什么网站?
北京制作网站的公司,北京铁路集团官方网站?
攀枝花网站建设,攀枝花营业执照网上怎么年审?
网站制作服务平台,有什么网站可以发布本地服务信息?
c# Task.Yield 的作用是什么 它和Task.Delay(1)有区别吗
网站设计制作企业有哪些,抖音官网主页怎么设置?
湖南网站制作公司,湖南上善若水科技有限公司做什么的?
如何在IIS管理器中快速创建并配置网站?
如何做静态网页,sublimetext3.0制作静态网页?
图片制作网站免费软件,有没有免费的网站或软件可以将图片批量转为A4大小的pdf?
如何快速搭建高效简练网站?
广州网站设计制作一条龙,广州巨网网络科技有限公司是干什么的?
定制建站模板如何实现SEO优化与智能系统配置?18字教程
如何用PHP工具快速搭建高效网站?
GML (Geography Markup Language)是什么,它如何用XML来表示地理空间信息?
免费的流程图制作网站有哪些,2025年教师初级职称申报网上流程?
,如何利用word制作宣传手册?
深圳网站制作设计招聘,关于服装设计的流行趋势,哪里的资料比较全面?
如何选择适配移动端的WAP自助建站平台?
广州顶尖建站服务:企业官网建设与SEO优化一体化方案
如何有效防御Web建站篡改攻击?
如何选择高效稳定的ISP建站解决方案?
装修招标网站设计制作流程,装修招标流程?
如何用景安虚拟主机手机版绑定域名建站?
企业微网站怎么做,公司网站和公众号有什么区别?
IOS倒计时设置UIButton标题title的抖动问题
如何选购建站域名与空间?自助平台全解析
如何解决ASP生成WAP建站中文乱码问题?
,网页ppt怎么弄成自己的ppt?
建站之星与建站宝盒如何选择最佳方案?
如何制作公司的网站链接,公司想做一个网站,一般需要花多少钱?
*服务器网站为何频现安全漏洞?
如何快速搭建高效服务器建站系统?
如何配置WinSCP新建站点的密钥验证步骤?
,网站推广常用方法?
公司门户网站制作流程,华为官网怎么做?
如何在阿里云购买域名并搭建网站?
制作假网页,招聘网的薪资待遇,会有靠谱的吗?一面试又各种折扣?
制作网站的软件免费下载,免费制作app哪个平台好?
建站主机核心功能解析:服务器选择与网站搭建流程指南
*请认真填写需求信息,我们会在24小时内与您取得联系。