Python中令人困惑的操作符
操作符對(duì)于現(xiàn)代編程來(lái)說(shuō)絕對(duì)是一個(gè)至關(guān)重要的組成部分。它們通常用于數(shù)學(xué)運(yùn)算。Python編程語(yǔ)言有一系列不同的操作符,并且不斷添加新的操作符。
有一個(gè)運(yùn)算符具有一些相當(dāng)有趣的功能和特點(diǎn),那就是加等運(yùn)算符。乍一看,這似乎只是加法和等于操作符的基本組合。雖然可能是這樣,但有一些非常有趣的特性使該操作符與眾不同。今天,我想展示這個(gè)操作符的一些有趣的特點(diǎn)和特性。
概述
在深入研究這個(gè)奇怪的操作符之前,我們可能應(yīng)該熟悉一下該語(yǔ)言中通常如何使用這個(gè)操作符。在這個(gè)意義上,加號(hào)等于可以被認(rèn)為是加法和斷言的捷徑。而不是像:
- x = 5
- xx = x + 5
- print(x)
- 10
我們可以這樣做:
- x = 5
- x += 5
- print(x)
當(dāng)然,這種操作符的使用取決于個(gè)人偏好。有些用戶可能更喜歡后一種方法,但在我個(gè)人看來(lái),我總是發(fā)現(xiàn)加號(hào)等于運(yùn)算符可以使這樣的表達(dá)式更加簡(jiǎn)潔。
可變?cè)M
您很可能熟悉Python中的元組和列表數(shù)據(jù)結(jié)構(gòu)。這是Python中兩種不同類型的可迭代一維數(shù)組,它們之間只有一個(gè)鍵差。元組是不可變的結(jié)構(gòu),這意味著一旦定義,元組就不能被更改。列表當(dāng)然是可變的,它包含了像append()這樣的方法。
雖然元組不是可變對(duì)象,但有一個(gè)關(guān)鍵的區(qū)別是許多程序員在觀察時(shí)忽略的。雖然元組本身可能不是可變的,但其中的類型仍然是可變的。元組仍然是一個(gè)數(shù)據(jù)結(jié)構(gòu),該元組中的數(shù)據(jù)仍然屬于其各自的類型。然而,Python仍然具有試圖改變不可變類型時(shí)可能會(huì)出現(xiàn)的拋出。考慮到這個(gè)功能,我們可以預(yù)期下面的代碼會(huì)顯示一個(gè)錯(cuò)誤,說(shuō)明元組是不可變的。
- z = (5, 10, 15)
- z[4] = 15
然而,為了證明元組中包含的數(shù)據(jù)仍然是可變的,如果我們要從元組中取出一些數(shù)據(jù),我們可以對(duì)它進(jìn)行修改:
- newnum = z[3]
- newnum = z[2]
- newnum += 5
- print(newnum)
- 20
考慮下面的列表元組:
- letters = (["S", "T"],
- ["A", "D"])
元組本身是一個(gè)不可變類型。但是,其中的列表,一個(gè)字母在字母L后面,另一個(gè)字母在字母L前面,仍然是可變的。如果我們現(xiàn)在試著在這張單子上再加一封信,你覺(jué)得會(huì)發(fā)生什么?
- letters[0] += "Q"
正如預(yù)期的那樣,我們得到了另一個(gè)類型錯(cuò)誤,因?yàn)樵M一旦創(chuàng)建就不能更改。但是,只有在對(duì)數(shù)據(jù)結(jié)構(gòu)調(diào)用操作符后才會(huì)拋出此類型錯(cuò)誤。換句話說(shuō),我們可能遇到了異常,但如果我們現(xiàn)在從元組中打印出列表,我們將看到元素實(shí)際上已經(jīng)被添加到列表中:
- print(letters[0])
- ['S', 'T', 'Q']
需要注意的是,它不能直接處理數(shù)據(jù)類型。Python的有趣之處在于,在基類內(nèi)部的數(shù)據(jù)類型和我們可能在基類外部使用的數(shù)據(jù)類型之間基本上沒(méi)有關(guān)鍵區(qū)別。這意味著我們實(shí)際上可以用純Python重寫(xiě)這些類型。這與大多數(shù)語(yǔ)言不同,后者通常包括在語(yǔ)言本身中沒(méi)有結(jié)構(gòu)化的基礎(chǔ)數(shù)據(jù)類型。
信不信由你,這種類型錯(cuò)誤和元組可變性是Python的特性,而不是bug。乍一看,這里似乎犯了某種錯(cuò)誤,但考慮到Python的方法學(xué),這一切在某種程度上確實(shí)是有意義的。這一切都與Python如何處理數(shù)據(jù)有關(guān),更重要的是,plus-equals如何處理不同的數(shù)據(jù)類型。這就是為什么正等號(hào)這么棒的部分原因!
仔細(xì)看看
現(xiàn)在我們已經(jīng)知道了加號(hào)等于運(yùn)算符有多奇怪,為了更好地理解其用法中的怪異之處,讓我們來(lái)看看該運(yùn)算符實(shí)際上是如何工作的。當(dāng)然,這將是這個(gè)操作符上相同函數(shù)的Python實(shí)現(xiàn)的一個(gè)更粗略的版本。代碼看起來(lái)就像我們期望的那樣:
- def plusequals(num1, num2):
- total = num1.__iadd__(num2)
- num1 = total
然而,每當(dāng)我們使用更大的表達(dá)式,而不是簡(jiǎn)單的數(shù)據(jù)類型時(shí),我們可以考慮代碼看起來(lái)更類似于以下內(nèi)容:
- def plusequals(x[0], element):
- total = x[0].__iadd__(element)
- x[0] = total
當(dāng)然,正如我們前面提到的,從元組中提取的元素完全可以添加元素。然而,當(dāng)我們將x的第一個(gè)(第0個(gè))索引賦值給新的總數(shù)時(shí),就會(huì)遇到元組的類型錯(cuò)誤。
原文鏈接:
https://towardsdatascience.com/pythons-most-confusing-operator-96c67d6e661a
























