在我们使用Python的过程中, 经常遇到赋值语句, 就像下面的那样:

a = 3

b = 3

可能你会觉得我又要说什么变量赋值就是引用, 这么简单的知识就不讨论啦, 相信聪明的大家肯定都知道的, 我想讲的是链式赋值

先科普下什么是链式赋值:

链式赋值: 同时对几个变量进行赋值

例如:

a = b = c = 3

好了, 现在正式进入正题:

>>> s = [1, 2, 3, 4, 5, 6]

>>> i = 0

>>> i = s[i] = 3

i 和 s 的值分别是什么? 可能大家一眼看下去, 就能得出答案:

i 的值: 3

s 的值: [3, 2, 3, 4, 5, 6]

然而, 这个答案只是对了一半, 因为s的值错了! 有兴趣的朋友可以自行上机试下, 正确答案是:

i 的值: 3

s 的值: [1, 2, 3, 3, 5, 6]

s的列表, 并没有像我们想象中的那样, 就i=0位置上的元素, 变成3, 而是将i=3位置的元素改成3了, 为什么会这样? 一起来解析下吧, 上dis大杀器!

[root@iZ23pynfq19Z ~]# cat 2.py

s = [1, 2, 3, 4, 5]

i = 0

g = i = s[i] = 3

[root@iZ23pynfq19Z ~]# python -m dis 2.py

1 0 LOAD_CONST 0 (1)

3 LOAD_CONST 1 (2)

6 LOAD_CONST 2 (3)

9 LOAD_CONST 3 (4)

12 LOAD_CONST 4 (5)

15 BUILD_LIST 5

18 STORE_NAME 0 (s)

2 21 LOAD_CONST 5 (0)

24 STORE_NAME 1 (i)

3 27 LOAD_CONST 2 (3)

30 DUP_TOP

31 STORE_NAME 2 (g)

34 DUP_TOP

35 STORE_NAME 1 (i)

38 LOAD_NAME 0 (s)

41 LOAD_NAME 1 (i)

44 STORE_SUBSCR

45 LOAD_CONST 6 (None)

48 RETURN_VALUE

第一列的数字, 代表中间的字节码是属于哪一行代码的.

第1~2行简单解释下:

分别LOAD_CONST5个数字, 组成一个列表, 赋值给s,再取一个0, 赋值给i.接下来的就是我们关心的, 也是带给我们意外的代码.

第3行:

LOAD_CONST取出常量3, 它并不是像上面执行STORE_NAME, 而是采用DUP_TOP, 这是什么鬼, 我们这要去看下这指令具体是干嘛的:

//取自 python/ceval.c

PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)

{

... (省略)

TARGET_NOARG(DUP_TOP)

{

v = TOP(); // 复制运行栈帧的顶部值

Py_INCREF(v); // 增加引用计数

PUSH(v); // 再压入运行栈帧

FAST_DISPATCH();

}

... (省略)

}

DUP_TOP指令说白了, 就是将刚才LOAD_CONST指令取出的常量3, 复制一份给v,然后再压回去运行栈帧, 这样就有两个3了, 为什么要这么做, 肯呢个大家已经猜到了, 不过我们还是得继续看具体是不是像我们想的那样, 继续看会字节码:

35 STORE_NAME 1 (i)

38 LOAD_NAME 0 (s)

41 LOAD_NAME 1 (i)

44 STORE_SUBSCR

果然不出我们所料, 开始将这些3通过STORE_NAME赋值给i, 而对于s, 它反而是, 再一次LOAD_NAME取出i的值, 此时i的值是3, 不是一开始的0了, 在通过STORE_SUBSCR指令, 将刚才压入运行时时栈的3赋值给位置是3的元素, 具体的源码就不再看, 到这就够了.

所以看到这, 相信大家都能清楚, 为什么结果是 [1, 2, 3, 3, 5, 6]

这跟我们想象中的链式赋值很不同, 我们以前总是觉得, 赋值要从右到左依次执行, 先执行 s[i] = 3, 再执行 i=3, 然而这些是类似c语言这类支持表达式赋值才允许的. 在c语言中, s = 3表达式是有返回值的. 它会返回赋值的结果3, 所以在它们的链式赋值中, 是将右边表达式的返回值, 再赋值给左边的, 例如:

a = s = 3

等价于:

a = (s = 3)

也就是 s=3 返回3, 再赋值给a

而在python是不支持这种表达式赋值的, 也就是表达式是没有返回值的, 如果硬要a = (s = 3)只会触发SyntaxError: invalid syntax

希望大家以后在用到这种链式赋值时, 尽量避免这些问题哦

感谢@Daetalus童鞋指出问题:

支持表达式赋值是Python语言的核心,比如a = b + 3。这里的 b + 3

就是表达式。如果不支持表达式赋值就没法继续下去了。

a = (s = 3)出错的原因是因为s = 3是赋值语句,而不是表达式。

Python的表达式是由操作符连接而成的,但“=”在Python中并不是操作符(Operator),只是语法分隔符(Delimiters)。参见https://docs.python.org/relea...

python支持链式赋值和多重赋值_Python: 链式赋值的坑相关推荐

  1. python中赋值不正确的_python中关于赋值、浅拷贝与深拷贝的问题

    Python中关于对象复制有三种类型的使用方式,赋值.浅拷贝与深拷贝.他们既有区别又有联系,刚好最近碰到这一类的问题,研究下. 一.赋值 在python中,对象的赋值就是简单的对象引用,这点和C++不 ...

  2. python中赋值不正确的_python中的“赋值与深浅拷贝”

    Python中,赋值与拷贝(深/浅拷贝)之间是有差异的,这主要源于数据在内存中的存放问题,本文将对此加以探讨. 1 赋值(添加名字) 赋值不会改变内存中数据存放状态,比如在内存中存在一个名为data的 ...

  3. python中函数可以赋值给一个变量_python中函数赋值给变量时的问题注意详解

    变量赋值是我们在日常开发中经常会遇到的一个问题,下面这篇文章主要给大家介绍了关于python中将函数赋值给变量时需要注意的一些问题,文中通过示例代码介绍的非常详细,对大家具有一定的参考学习价值,需要的 ...

  4. python支持复数以及相关的运算吗_python复数运算

    广告关闭 腾讯云11.11云上盛惠 ,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元! 和大多数语言一样,python也有很多运算符,并且运算符跟其他语言的运算符大同小 ...

  5. python支持复数以及相关的运算吗_python怎么实现复数运算

    复数的数学运算 复数可以用使用函数 complex(real, imag) 或者是带有后缀j的浮点数来指定.比如:>>> a = complex(2, 4) >>> ...

  6. python支持复数以及相关的运算吗_Python: 复数的数学运算

    写的最新的网络认证方案代码遇到了一个难题,唯一的解决办法就是使用复数空间,需要使用复数来执行一些计算操作. 复数可以用使用函数complex(real, imag) 或者是带有后缀j 的浮点数来指定. ...

  7. python支持复数以及相关的运算吗_Python复数属性和方法运算操作示例

    本文实例讲述了Python复数属性和方法运算操作.分享给大家供大家参考,具体如下: #coding=utf8 ''''' 复数是由一个实数和一个虚数组合构成,表示为:x+yj 一个负数时一对有序浮点数 ...

  8. python支持按指定字符串分割成数组_python – 如何切割numpy数组字符串的每个元素?...

    这是一个矢量化的方法 – def slicer_vectorized(a,start,end): b = a.view('S1').reshape(len(a),-1)[:,start:end] re ...

  9. python支持复数以及相关的运算吗_Python支持复数以及相关的运算。

    [填空题]Linux系统中/dev/sda3 表示 [简答题]作出三棱锥的截交线 [简答题]简述一致性网络设备名" enp0s8 "的含义. [简答题]把今天手工绘制的锥度.斜度. ...

最新文章

  1. Linux常用命令大全-toolfk程序员在线工具网
  2. POJ2299 Ultra-QuickSort
  3. DWZ 在js中刷新某个navTab
  4. rss的普及需要一个容易理解的中文名字,叫“新闻源”如何?
  5. JUnit5 TestSuite替代
  6. sql怎么撤回update_零基础快速自学SQL,2天足矣!
  7. 全志a33android编译,编译lichee - 全志A33的环境搭建
  8. php xml 实例教程,php解析xml方法实例详解,解析xml实例详解_PHP教程
  9. RabbitMQ-使用@RabbitListener注解消费消息
  10. sql语句ding_在postgresql中结束掉正在执行的SQL语句操作
  11. tomcat7中get请求中文乱码问题
  12. 三年高级开发,六年成为架构师,到CTO我用了12年
  13. 爆笑的虫子机器人_《爆笑虫子Larva》全集目录
  14. ospf多区域的原理和配置实例
  15. JAVA实现功能的方法
  16. forgot XCTF(你的疑问都可以在这里找到答案)
  17. 检查企业71万余家(次),查处椎
  18. 漫画:二分法系列篇(第一讲)
  19. 利用SUMO模拟事故
  20. 计算机科学ESI 2020年7月,2020年7月ESI学科高水平论文134篇

热门文章

  1. 终于还是对“带薪拉SHI”出手了...
  2. 微服务网关 Kong 快速上手攻略
  3. 工控攻防演示——从外网到内网控制系统设备的入侵
  4. 牛腩知识小结-盒子模型
  5. python点到多边形距离,点到轮廓距离
  6. 大厂常见笔试题 滑动窗口内数的和
  7. python 利用多进程实现文件的拷贝
  8. tf torch keras 数据增强 data augmentation
  9. TensorFlow实现案例汇集:代码+笔记
  10. ffmpeg + x264+ x265 + libde265 + opengl es display