python關於+=的陷阱
看下面程式碼
t = (1, 2, [30, 40])
t[2] += [50, 60]
我們知道tuple元組是個不可變元素,所以更改元組的元素道理上是不行的,但是我改變的元素是個列表,它本身是可變的,這樣可行嗎??
先別去控制檯執行,猜是下面哪一種:
- t 變成 (1, 2, [30, 40, 50, 60])。
- 因為 tuple 不支援對它的元素賦值,所以會丟擲 TypeError 異常。
- 以上兩個都不是。
- a 和 b 都是對的。
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
答案是第四種情況
我們使用Python Tutor(http://www.pythontutor.com)對執行程式碼進行視覺化
最後我們看看背後的位元組碼是怎麼執行s[a] += b這種操作的
到1是將 s[a] 的值存入 TOS(Top Of Stack,棧的頂端)
到2是計算 TOS += b。這一步能夠完成,是因為 TOS 指向的是一個可變物件
到3是s[a] = TOS 賦值。這一步失敗,是因為 s 是不可變的元組
所以才會出現即操作成功又報異常的現象
教訓:
- 不要把可變物件放在元組裡面
- 增量賦值不是一個原子操作(從位元組碼可以看出經過了若干步)
相關文章
- 關於js陣列方法sort()負數排序的陷阱JS陣列排序
- 關於Netty的一些理解、實踐與陷阱Netty
- 潛在的Python陷阱Python
- Python字典遍歷的陷阱Python
- Python技巧和陷阱Python
- 關於 Python 的 importPythonImport
- 十二個坑爹的Python陷阱Python
- 關於程式碼覆蓋率,你不可不知的兩大陷阱!
- 關於pythonPython
- 關於Python的迭代操作Python
- 關於Python的集合setPython
- 坑爹的Python陷阱(避坑指南)Python
- python的socket.recv函式陷阱Python函式
- 關於Python Number 相關的知識!Python
- python:關於pipPython
- 關於Python的super用法研究Python
- python中from module import * 的一個陷阱PythonImport
- Python--關於dictPython
- Python--關於setPython
- 8個關於Python的小技巧Python
- 關於Python中的日期處理Python
- 關於python訪問字典的方法Python
- 關於python中的setup.pyPython
- 陷阱!python引數預設值Python
- 開發中常遇到的Python陷阱和注意點Python
- 關於高效使用Python字典的清單Python
- 關於Python閉包的一切Python
- 關於python中slicing的探討Python
- 關於Python的面相物件程式設計Python物件程式設計
- 關於python的cx_Oracle安裝PythonOracle
- 關於Python 3的一些想法Python
- 關於Python多執行緒的理解Python執行緒
- 關於Python小遊戲程式Python遊戲
- 關於python整合dlibPython
- Python中的一些陷阱與技巧小結Python
- 關於引用(python中的偽指標)的理解Python指標
- 關於python建構函式的過載Python函式
- 最新進展|關於Python治理模式的投票Python模式