Python:那些年我們遇到的坑
一、走丟的外部變數
首先我們先來看這麼一個例子:
e = 429 try: raise Exception() except Exception as e: pass print(e)
PS:except Exception as e 可以捕獲除了與程式退出(sys.exit())相關之外的所有異常。
在繼續向下看之前,你可以先思考一下上述例子可能出現的結果是什麼,也可以自己嘗試著在編譯器裡輸入一下。思考完了請繼續往下看。
出現的結果如下:
Traceback (most recent call last): File "test.py", line 8, in <module> print(e) NameError: name 'e' is not defined
竟然報錯了,那麼這到底是為什麼呢?
其實這是因為在 Python3 中使用 as 分配異常的時候,在 except 的末尾將會把這個異常清除掉(在 Python2 中則不會出現這樣的情況)。這就好像將上面的示例變成下面的樣子:
e = 429 try: raise Exception() except Exception as e: try: pass finally: del e print(e)
透過上面的變形程式碼,我們可以很清楚的看明白髮生這一切的根源是什麼:因為 e 被刪除了。這也變相的告訴我們,如果想要在 except 後面引用 e,必須將它先賦值給其它變數。
這樣看來,是變數 e 執行了 except 子句而被刪除,但是為什麼 e 會去執行 except 子句呢?僅僅是因為 e 和 as 後面的 e 長的一毛一樣?
答案是否定的,其實這個是因為子句在 Python 中沒有獨立的作用域,所以上述示例中的所有內容都處於同一個作用域裡,所以變數 e 會因為執行了 except 子句而被刪除。
二、同樣是加,卻不一定等價
在我們來表示「加」這個概念的時候,一般我們會用兩種方式:a = a + b或者是 a += b 。在很多人的概念裡這兩個其實就是一種,不分彼此,比如之前我就是這麼認為的,直到有一天有人拿著下面的坑過來讓我踩...
首先我們先來看第一個例子:
>>> a = [1,2,3] >>> b = a >>> a = a + [4,5,6]
一個很簡單的例子,你知道此時的 a 和 b 分別是多少麼?請先自己思考一下再繼續向下看:
>>> a [1, 2, 3, 4, 5, 6] >>> b [1, 2, 3]
估計很多人都會答對,表示式 a = a + [4,5,6] ,等號右邊其實是形成了一個新的列表,最後讓 a 引用了這個新的列表,而 b = a 引用的是之前的 a,所以 b 保持不變。
明白了上面的例子,我們接下來再看一個稍微有點區別的例子:
>>> a = [1,2,3] >>> b = a >>> a += [4,5,6]
上面的例子和文章開頭的例子區別在從 + 變成了 +=,按照我們慣性思維去想,肯定以為這倆例子就是一個東西的兩種不同寫法而已,可實際上真的是這樣嗎?讓我們來看一下此時的 a,b:
>>> a [1, 2, 3, 4, 5, 6] >>> b [1, 2, 3, 4, 5, 6]
咦?同樣是印象裡的「加」,好像真的哪裡有點不一樣誒。。
透過上面我們就可以看出 a = a + b 和 a += b 並不總是表現相同,起碼在列表上就是這麼表現的。在這裡的 a += [4,5,6] 實際上使用的是 extend 函式,所以 a 和 b 仍然指向已被修改的同一列表。
既然在這裡說到了 + 和 +=,索性再多補充一點:在使用「加」的概念來連線字串的時候,+= 其實比 + 的速度更快。
下面我們來實際的演示一下用 + 連線三個字串:
>>> import timeit >>> timeit.timeit("a = a + b + c", setup="a='a'*10000;b='b'*10000;c='c'*10000",number=100) 0.07921688999340404 >>> timeit.timeit("a += b + c", setup="a='a'*10000;b='b'*10000;c='c'*10000",number=100) 0.002059974998701364
上面的兩個結果很容易看出來,在處理速度上,+= 比 + 處理的速度要快的多。出現這樣現象的原因是 += 執行的是追加操作,追加操作的話就會比 + 少了一個銷燬然後新建的動作,比如在 a += b + c 上 a 就不會被銷燬。
三、不一般的小括號
很多學過別的程式語言的同學,很容易會忽略小括號 “()” 在 Python 中的一個重要表現,那就是小括號還能表示“元組” 這一不可變資料型別。
>>> type(()) <class 'tuple'> >>> tur = (1, 2) >>> type(tur) <class 'tuple'>
但是如果小括號內只有一個元素的話,比如像下面這樣,它就是小括號內的元素型別:
>>> tur = (1) >>> type(tur) <class 'int'>
天吶個天...
那麼如果想要表示一個元素的元組咋整呢?要像下面這樣:
>>> tur = (1, ) >>> type(tur) <class 'tuple'>
加個逗號 “,” 就 ok 啦...
四、列表的刪除沒有那麼簡單
假如我們有一個列表,我想刪除列表中的元素:
>>> lst = [1, 2, 3, 4, 5] >>> for i in lst: ... lst.remove(i)
在剛開始學習 Python 之初,這是很多同學容易想到的做法,然而我們來看一下程式執行完以後的結果:
>>> lst [2, 4]
看到這個結果,我...
這是為啥子呢?是因為在 for 迴圈中,如果我們刪除了 index = 0 (即 1)的值,原本 index = 1 及其之後的值會向前補位,所以當前 index = 1 的值為之前 index = 2 的值。
列表的刪除操作我們經常要用,所以大家要打起十二分的精神來對它。
五、is not 不分家
is not 在 Python 中是一夥的,用的時候要靠在一起,分開以後就是兩個東西,結果會不一樣。
>>> [1, 2, 3] is not None True >>> [1, 2, 3] is (not None) False
這就在於,is not 是個單獨的二元運算子,當它兩側的變數指向同一個物件的時候,結果為 False,否則結果為 True,希望引起大家的注意。
python學習網,免費的線上學習,歡迎關注!
本文轉自:https://blog.csdn.net/u013486414/article/details/103180951
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/756/viewspace-2835357/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 【iOS】那些年,遇到的小坑iOS
- 那些年我們一起踩過的Dubbo坑
- 那些年,我們一起走過的iOS推送的坑iOS
- 小程式開發,那些我們跳過的坑
- phalcon遇到的那些坑
- 使用WebDriver遇到的那些坑Web
- 進擊的Bug 那些年我遇到的大坑
- 進擊的Bug 那些年我遇到的大坑2
- 我們不要送人頭!出海日本的那些坑與躲避的技巧
- 那些年,我們解析過的前端異常前端
- 進擊的Bug---那些年我遇到的大坑3
- Apple Watch應用開發經驗談:我遇到的那些坑APP
- 那些年,我們處理過的SQL問題SQL
- 那些年,我們一起追過的APPAPP
- 使用vue匯出excel遇到的那些坑VueExcel
- 異常處理遇到過的那些坑
- 微信小程式開發遇到的那些坑微信小程式
- 那些前端工作中遇到的坑(01)前端
- 在選擇資料庫的路上,我們遇到過哪些坑?(2)資料庫
- 在選擇資料庫的路上,我們遇到過哪些坑?(1)資料庫
- 那些年,我們看不懂的那些Kotlin標準函式Kotlin函式
- Python裡的那些坑Python
- 那些年,我們用過的伺服器軟體伺服器
- 那些年讓我們頭疼的CSS3動畫CSSS3動畫
- 那些年,我們一起誤解過的RESTREST
- 致畢業生:那些年我們錯過的“BAT”BAT
- 支付寶APP接入的那些坑們APP
- 那些年,我們見過的 Java 服務端“問題”Java服務端
- 那些年,我們一起追過的化學元素
- 我踩過的聽過的那些坑
- 區塊鏈私有鏈搭建中遇到的那些坑區塊鏈
- iOS開發中遇到的那些坑,持續更新iOS
- 坑!坑!坑!那些年運營犯過的錯誤
- 那些年,我們又愛又恨的HashMap(二)-原始碼篇HashMap原始碼
- 那些年我們一起擼過的快取寫法快取
- 那些年,我們北漂的日子--(工作第3,4,5天)
- 使用Docker網路解決方案weave遇到的那些坑Docker
- 我們自研的那些Devops工具dev