一個(gè)關(guān)于 += 的謎題

原文鏈接: 一個(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è)備選答案:

  1. t 變成 (1, 2, [3, 4, 5, 6])
  2. 因?yàn)?tuple 不支持對(duì)它的元素賦值,所以會(huì)拋出 TypeError 異常。
  3. 以上兩個(gè)都不是。
  4. 以上兩個(gè)都是對(duì)的。

當(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è)方面來解釋:

一、對(duì)象類型

Python 中的對(duì)象可以分成兩類,可變對(duì)象和不可變對(duì)象,比如一些內(nèi)置類型:

  1. 可變對(duì)象:list,set,dict。
  2. 不可變對(duì)象:int,float,bool,string,tuple。

舉一個(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é)碼

首先解釋一下字節(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)鍵三步:

  1. 4 DUP_TOP_TWO:將 s[a] 存入 TOS(Top Of Stack)。
  2. 10 INPLACE_ADD:執(zhí)行 TOS += b,帶入到文章開頭的表達(dá)式,就相當(dāng)于向 t[2] 中添加元素,因?yàn)?t[2] 是 list,可變對(duì)象,所以這一操作沒有問題。
  3. 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):

  1. 不要把可變對(duì)象放在元組里面。
  2. 增量賦值不是一個(gè)原子操作。我們剛才也看到了,它雖然拋出了異常,但還是完成了操作。
  3. 查看 Python 的字節(jié)碼并不難,而且它對(duì)我們了解代碼背后的運(yùn)行機(jī)制很有幫助。

以上就是本文的全部?jī)?nèi)容,如果覺得還不錯(cuò)的話,歡迎點(diǎn)贊轉(zhuǎn)發(fā),多謝


推薦閱讀:

  • 計(jì)算機(jī)經(jīng)典書籍(含下載方式)
  • 技術(shù)博客: 硬核后端開發(fā)技術(shù)干貨,內(nèi)容包括 Python、Django、Docker、Go、Redis、ElasticSearch、Kafka、Linux 等。
  • Go 程序員: Go 學(xué)習(xí)路線圖,包括基礎(chǔ)專欄,進(jìn)階專欄,源碼閱讀,實(shí)戰(zhàn)開發(fā),面試刷題,必讀書單等一系列資源。
  • 面試題匯總: 包括 Python、Go、Redis、MySQL、Kafka、數(shù)據(jù)結(jié)構(gòu)、算法、編程、網(wǎng)絡(luò)等各種常考題。

分享名稱:一個(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)

手機(jī)網(wǎng)站建設(shè)
主站蜘蛛池模板: 久久精品无码一区二区三区不卡| 亚洲日韩精品无码专区加勒比| 日韩夜夜高潮夜夜爽无码| 亚洲中文字幕无码爆乳| 好爽毛片一区二区三区四无码三飞 | 日韩免费人妻AV无码专区蜜桃| 亚洲一区AV无码少妇电影☆| 秋霞鲁丝片Av无码少妇| 午夜成人无码福利免费视频| 丰满熟妇人妻Av无码区| 真人无码作爱免费视频| 久久久无码人妻精品无码| 红桃AV一区二区三区在线无码AV | 国产精品无码久久久久久| 性色av极品无码专区亚洲| 亚洲精品无码Av人在线观看国产| 亚洲a∨无码精品色午夜| 精品人妻大屁股白浆无码| av无码一区二区三区| 亚洲AV成人无码网天堂| 中文字幕日产无码| 亚洲AV无码AV男人的天堂| 免费看无码特级毛片| 国产人成无码视频在线观看| 亚洲成a人片在线观看天堂无码 | 亚洲人AV在线无码影院观看| 国产成A人亚洲精V品无码 | 少妇无码太爽了不卡在线观看| 亚洲AV无码资源在线观看| 人妻无码αv中文字幕久久琪琪布 人妻无码第一区二区三区 | 久久亚洲精品成人无码网站| 亚洲精品无码乱码成人| 亚洲一区二区三区无码中文字幕| 成人无码AV一区二区| 亚洲精品无码成人片在线观看 | 成年免费a级毛片免费看无码| 日韩无码系列综合区| 成人免费无遮挡无码黄漫视频| 97无码免费人妻超级碰碰碰碰 | 亚洲av无码乱码在线观看野外| 麻豆亚洲AV成人无码久久精品 |