python链式赋值有哪些注意事项?,,在我们在python


在我们在python开发http://www.maiziedu.com/land/python/中,经常遇到赋值语句,就像下面的那样: a = 3b = 3 可能你会觉得我又要说什么变量赋值就是引用,这么简单的知识就不讨论啦,相信聪明的大家肯定都知道的,本文和大家分享的是链式赋值相关内容,一起来看看吧,希望对大家学习和使用这部分内容有所帮助。 先科普下什么是链式赋值: 链式赋值:同时对几个变量进行赋值 例如: a = b = c = 3 好了,现在正式进入正题: >>> s = [1, 2, 3, 4, 5, 6]>>> i = 0>>> i = s= 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,intthrowflag) { ... (省略) 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= 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 希望大家以后在用到这种链式赋值时,尽量避免这些问题哦 来源:SegmentFault

python链式赋值有哪些注意事项?

相关内容

    暂无相关文章

评论关闭