原文鏈接: 一個(gè)關(guān)于 += 的謎題
站在用戶的角度思考問題,與客戶深入溝通,找到從化網(wǎng)站設(shè)計(jì)與從化網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗(yàn),讓設(shè)計(jì)與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個(gè)性化、用戶體驗(yàn)好的作品,建站類型包括:成都做網(wǎng)站、網(wǎng)站建設(shè)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、域名注冊(cè)、網(wǎng)站空間、企業(yè)郵箱。業(yè)務(wù)覆蓋從化地區(qū)。
今天在看書過程中發(fā)現(xiàn)了一個(gè)問題,還挺有意思的,分享給大家。
下面兩個(gè) Python 表達(dá)式會(huì)產(chǎn)生什么結(jié)果?
t = (1, 2, [3, 4])
t[2] += [5, 6]
給四個(gè)備選答案:
t
變成 (1, 2, [3, 4, 5, 6])
。TypeError
異常。當(dāng)時(shí)看到這個(gè)問題,第一反應(yīng)就是選 2。因?yàn)?tuple 是不可變對(duì)象,不支持對(duì)它的元素賦值,會(huì)報(bào)錯(cuò)。
但事實(shí)上,這道題的正解是 4。
在終端里驗(yàn)證一下:
Python 3.8.2 (default, Oct 2 2020, 10:45:42)
[Clang 12.0.0 (clang-1200.0.32.27)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>> t = (1, 2, [3, 4])
>>> t[2] += [5, 6]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
結(jié)果是沒問題的,t
被修改了,但是也報(bào)錯(cuò)了。
還可以在 Python Tutor 上分析一下:
網(wǎng)站地址: https://pythontutor.com/
這個(gè)網(wǎng)站可以可視化分析 Python 的運(yùn)行過程和原理。
執(zhí)行第一個(gè)表達(dá)式:
執(zhí)行第二個(gè)表達(dá)式:
為什么會(huì)這樣呢?可以從兩個(gè)方面來解釋:
Python 中的對(duì)象可以分成兩類,可變對(duì)象和不可變對(duì)象,比如一些內(nèi)置類型:
舉一個(gè)例子:
可變對(duì)象:
>>> a = [1, 2, 3]
>>> id(a)
>>> b = a
>>> id(b)
>>> a[1] = 4
>>> a
[1, 4, 3]
>>> b
[1, 4, 3]
>>> id(a)
>>> id(b)
可以看到,改變 a
的同時(shí) b
也跟著變,因?yàn)樗麄兪冀K指向同一個(gè)地址。
不可變對(duì)象:
>>> a = (1, 2, 3)
>>> id(a)
>>> b = a
>>> a = (4, 5, 6)
>>> a
(4, 5, 6)
>>> b
(1, 2, 3)
>>> id(a)
>>> id(b)
可以看到,a
的值改變后,它的地址也發(fā)生了變化,而 b
還是原來的地址,并且原地址中的內(nèi)容也沒有發(fā)生變化。
首先解釋一下字節(jié)碼是什么?
Python 執(zhí)行程序時(shí)會(huì)把源碼文件編譯成字節(jié)碼文件,存放在 __pycahe 目錄內(nèi),文件用 .pyc
結(jié)尾。之后如果不再修改源碼文件,運(yùn)行時(shí)則直接使用 .pyc
文件編譯成機(jī)器碼,這樣不但運(yùn)行速度快,而且支持多個(gè)操作系統(tǒng)。
字節(jié)碼,其實(shí)就是一種中間代碼。
下面用 dis 模塊來看一下表達(dá)式 s[a] += b
的執(zhí)行過程:
>>> import dis
>>> dis.dis('s[a] += b')
1 0 LOAD_NAME 0 (s)
2 LOAD_NAME 1 (a)
4 DUP_TOP_TWO
6 BINARY_SUBSCR
8 LOAD_NAME 2 (b)
10 INPLACE_ADD
12 ROT_THREE
14 STORE_SUBSCR
16 LOAD_CONST 0 (None)
18 RETURN_VALUE
>>>
通過分析字節(jié)碼,可以看到其中的關(guān)鍵三步:
4 DUP_TOP_TWO
:將 s[a]
存入 TOS(Top Of Stack)。10 INPLACE_ADD
:執(zhí)行 TOS += b
,帶入到文章開頭的表達(dá)式,就相當(dāng)于向 t[2]
中添加元素,因?yàn)?t[2]
是 list,可變對(duì)象,所以這一操作沒有問題。14 STORE_SUBSCR
:將結(jié)果保存回 s[a] = TOS
,這相當(dāng)于將結(jié)果重新賦值回 t
,由于 t
是 tuple,不可變對(duì)象,所以報(bào)錯(cuò)。雖然這個(gè)問題在平時(shí)開發(fā)中可能并不常見,但通過分析還是有不少知識(shí)點(diǎn)可以深挖的。
簡(jiǎn)單總結(jié)以下三點(diǎn):
以上就是本文的全部?jī)?nèi)容,如果覺得還不錯(cuò)的話,歡迎點(diǎn)贊和轉(zhuǎn)發(fā),多謝
推薦閱讀:
分享名稱:一個(gè)關(guān)于 += 的謎題
轉(zhuǎn)載來于:http://m.kartarina.com/article44/dsojoee.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供微信小程序、移動(dòng)網(wǎng)站建設(shè)、網(wǎng)站維護(hù)、品牌網(wǎng)站設(shè)計(jì)、Google、網(wǎng)站收錄
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)