Python运算符+与+=的那些事

这两个运算符很多语言都提供了,好像也没啥好说的,不就是像下面这样子用嘛。

>>> x = 3 >>> y = x+6 >>> y 9 >>> x += 6 >>> x 9

+运算符得到新对象,当然也可以在原对象值的基础上进行增加,例如x = x+6;而+=总是修改原来的对象值。

但如果深入研究的话,情况似乎还是有些出乎意料的,看下面的代码:

>>> x = 3 >>> id(x) 1494131872 >>> x += 6 >>> id(x) 1494132064

其中内置函数id()用来返回一个对象的内存地址。那么上面的代码说明了什么呢?执行+=运算之后,x的内置地址发生了变化。究其原因,在于Python采用的是基于值的自动内存管理模式。变量中不直接存储值,而是存储值的引用,也就是值在内存中的地址。上面代码的执行过程如图所示,在执行x += 6时,首先把原来的3取出来,加上6得到9,把9放到内存中,最后再让x来指向这个新地址。

然而,当+和+=作用于列表时,情况又有所不同。

>>> x = [1, 2, 3] >>> id(x) 1668306802824 >>> x = x + [4] >>> id(x) 1668306565768 >>> x += [5] >>> id(x) 1668306565768

发现了什么?+=作用于列表时居然是原地操作,类似于列表的append()方法。确实是这样的。在类的设计中,特殊方法__iadd__()对应于+=运算符,而+运算符则对应于特殊方法__add__(),有例为证:

>>> class Test: def __init__(self, v): self.__value = [v] def __add__(self, vv): return Test(self.__value[0] + vv) def __iadd__(self, vv): self.__value.append(vv) return self def show(self): return self.__value

>>> t = Test(3) >>> t.show() [3] >>> id(t) 1668306894744 >>> tt = t+6 >>> tt.show() [9] >>> id(tt) 1668306197640 >>> t += 6 >>> t.show() [3, 6] >>> id(t) 1668306894744

既然这样的话,那么列表对象的+=也就是__iadd__()会设计成什么样子,就都是可以理解的了。

最后,如果元组中含有子列表,+=会有一个坑,详见Python编程中一定要注意的那些“坑”(一)

原文发布于微信公众号 - Python小屋(Python_xiaowu)

原文发表时间:2017-01-12

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏技术之路

详解JavaScript闭包

  要想完全明白JavaScript的闭包,要先明白js中的一些基础原理,然后我再给出一些例子来讲解闭包。   在执行JavaScript时会创建一个执行环境(...

271100
来自专栏C/C++基础

C++输入输出操作符重载

C++中输入操作符是>>,输出操作符是<<,又叫做流对象的“插入操作符”和“提取操作符“。其实这两个操作符最初是在C语言中用于整数的移位运算,到了C++中才利用...

9520
来自专栏用户3030674的专栏

java单例模式

单例设计模式:解决一个类在内存中只存在一个对象  多用于环境变量设置等  单例模式的要求:1.只能有一个对象,禁止其他程序建立该类对象          2....

11710
来自专栏mukekeheart的iOS之旅

《JavaScript高级程序设计》学习笔记(3)——变量、作用域和内存问题

欢迎关注本人的微信公众号“前端小填填”,专注前端技术的基础和项目开发的学习。 本节内容对应《JavaScript高级程序设计》的第四章内容。 1、函数:通过函数...

29660
来自专栏GreenLeaves

C# 命名空间和程序集

一、命名空间 1、通过使用using关键字引入命名空间,减少代码量 命名空间对相关的类型进行逻辑分组,通过命名空间能快速的定位到相关的类型,例如:在System...

23580
来自专栏转载gongluck的CSDN博客

c++ 中__declspec 的用法

c++ 中__declspec 的用法 语法说明: __declspec ( extended-decl-modifier-seq ) 扩展修饰符: ...

1.1K70
来自专栏云霄雨霁

Java--类和对象之基础知识

16430
来自专栏云霄雨霁

Java虚拟机--类加载过程

21280
来自专栏黑泽君的专栏

java基础学习_反射、装饰模式、JDK新特性_day27总结

10520
来自专栏积累沉淀

Java类加载原理机制

1.类的加载过程 JVM将类加载过程分为三个步骤:装载(Load),链接(Link)和初始化(Initialize)链接又分为三个步骤,如下图所示: ? 1...

305100

扫码关注云+社区

领取腾讯云代金券