徹底摧毀Python的有趣方式,我更改了1的值
我正在研究一篇文章,并且從Python文檔中發(fā)現(xiàn)了一個(gè)非常有趣的報(bào)價(jià):
當(dāng)前的實(shí)現(xiàn)為-5到256之間的所有整數(shù)保留一個(gè)整數(shù)對(duì)象數(shù)組,當(dāng)您在該范圍內(nèi)創(chuàng)建int時(shí),實(shí)際上實(shí)際上是返回對(duì)現(xiàn)有對(duì)象的引用。 因此應(yīng)該可以更改1的值。我懷疑在這種情況下Python的行為是不確定的。
Python中的所有內(nèi)容都是一個(gè)對(duì)象-包括數(shù)字。 這很重要,因?yàn)閿?shù)字-5 … 256是在運(yùn)行時(shí)分配的,訪問(wèn)它們會(huì)返回對(duì)該對(duì)象的引用,因此使您可以永久更改這些數(shù)字的值(在Python實(shí)例中)。 現(xiàn)在我還不知道它有多少實(shí)際用途,但確實(shí)很有趣。
熱身
您需要一些基本的C知識(shí)和ctypes庫(kù)。 首先,更改一個(gè)相對(duì)未使用的數(shù)字的值,例如31:
- >>> import ctypes
- >>> def changeNum(oldNum, newNum):
- ... ctypes.cast(id(oldNum), ctypes.POINTER(ctypes.c_int))[6] = newNum
- >>> changeNum(31, 100)
- # changes 31 to 100
- >>> 31100
讓我們嘗試一些基本的算法:
- >>> 31 + 31200
- >>> 31 ** 0.510.0
- >>> 31 ** 210000
此輸出使我感到非常不舒服,如果您也有這種感覺(jué),對(duì)即將發(fā)生的事情感到抱歉。 現(xiàn)在,讓我們真正運(yùn)行該手套:
- >>> 31 == 100
- True
- >>> changeNum(100, 200)
- >>> 31100
- >>> 100200
- >>> 31 == 100
- False
- >>> 31 == 200
- False
- >>> 31 * 2 == 200
- True>>> 31 * 2 == 100
- True
更改值后,它就消失了。 您可以嘗試找回原始值,但已將其刪除。
- >>> changeNum(100, 500 // 5)
- >>> 100200
- >>> changeNum(100, 50 * 2)
- >>> 100200
絕對(duì)混亂
如果您尚未意識(shí)到,則對(duì)象本身會(huì)進(jìn)行全局更改。 這意味著與該數(shù)字的任何交互都是"未定義的"。 讓我們看看行為在for循環(huán)中是如何"定義"的:
- >>> changeNum(5, 100)
- >>> for i in range(5):
- ... print(i)
- ...012
- ...99
相當(dāng)標(biāo)準(zhǔn); 作為一個(gè)不一致的數(shù)字系統(tǒng)可以得到的標(biāo)準(zhǔn)。 變得很奇怪:如果我更改5的值,則5在技術(shù)上不再存在。 這會(huì)導(dǎo)致基本操作中非常奇怪的交互:
- >>> changeNum(5, 20)
- >>> 5 - 7 == 13
- True
- >>> 5 - 7 - 8 == 5
- True
如果您真的想傷害您的大腦,請(qǐng)弄亂另外幾個(gè)數(shù)字并做一些數(shù)學(xué)運(yùn)算:
- >>> changeNum(29, 100)
- >>> changeNum(5, 20)
- >>> changeNum(120, 200)
- >>> 5 + 9100
- >>> 5 + 9 + 5200
- >>> 5 + 9 + 5 + 5220
- >>> (5 + 9) * 52000
您還可以制作一個(gè)非常令人困惑的無(wú)限while循環(huán):
- >>> while 5 // 4 == 5:
- ... pass
- ... # Do loop stuff
崩潰的Python
我們現(xiàn)在去釣大魚(yú)吧; 我們已經(jīng)解決了其他不重要的數(shù)字,但是如果我們改變1會(huì)發(fā)生什么?
- >>> changeNum(1, 2)
- >>> 1
- Segmentation fault (core dumped)
它崩潰了。 這不足為奇,因?yàn)?是非常重要的計(jì)算中使用的非常重要的數(shù)字。 我不確定更改1是否會(huì)影響True,但如果確實(shí)如此,我會(huì)想像一下后果。
最后的話
Python很棒,盡管這些交互很難看,但我仍然覺(jué)得它們很酷,希望您也這樣做。 您可以用它來(lái)惡作劇的朋友或同事,讓他們發(fā)瘋,因?yàn)樗麄冊(cè)噲D找出5不是5的原因。
沒(méi)有這篇Reddit帖子和令人驚嘆的GitHub存儲(chǔ)庫(kù),這篇文章是不可能的,我極力鼓勵(lì)將它們檢出。
感謝您與我共度這段時(shí)光。