彻底摧毁Python的有趣方式,我更改了1的值,


我正在研究一篇文章,并且从Python文档中发现了一个非常有趣的报价:

当前的实现为-5到256之间的所有整数保留一个整数对象数组,当您在该范围内创建int时,实际上实际上是返回对现有对象的引用。 因此应该可以更改1的值。我怀疑在这种情况下Python的行为是不确定的。

Python中的所有内容都是一个对象-包括数字。 这很重要,因为数字-5 … 256是在运行时分配的,访问它们会返回对该对象的引用,因此使您可以永久更改这些数字的值(在Python实例中)。 现在我还不知道它有多少实际用途,但确实很有趣。

热身

您需要一些基本的C知识和ctypes库。 首先,更改一个相对未使用的数字的值,例如31:

  1. >>> import ctypes 
  2. >>> def changeNum(oldNum, newNum): 
  3.   ... ctypes.cast(id(oldNum), ctypes.POINTER(ctypes.c_int))[6] = newNum 
  4. >>> changeNum(31, 100)  
  5. # changes 31 to 100 
  6. >>> 31100 

让我们尝试一些基本的算法:

  1. >>> 31 + 31200  
  2. >>> 31 ** 0.510.0  
  3. >>> 31 ** 210000 

此输出使我感到非常不舒服,如果您也有这种感觉,对即将发生的事情感到抱歉。 现在,让我们真正运行该手套:

  1. >>> 31 == 100  
  2. True  
  3. >>> changeNum(100, 200)  
  4. >>> 31100  
  5. >>> 100200  
  6. >>> 31 == 100  
  7. False  
  8. >>> 31 == 200  
  9. False  
  10. >>> 31 * 2 == 200  
  11. True>>> 31 * 2 == 100  
  12. True 

更改值后,它就消失了。 您可以尝试找回原始值,但已将其删除。

  1. >>> changeNum(100, 500 // 5)  
  2. >>> 100200  
  3. >>> changeNum(100, 50 * 2)  
  4. >>> 100200 

绝对混乱

如果您尚未意识到,则对象本身会进行全局更改。 这意味着与该数字的任何交互都是"未定义的"。 让我们看看行为在for循环中是如何"定义"的:

  1. >>> changeNum(5, 100)  
  2. >>> for i in range(5):  
  3. ... print(i)  
  4. ...012  
  5. ...99 

相当标准; 作为一个不一致的数字系统可以得到的标准。 变得很奇怪:如果我更改5的值,则5在技术上不再存在。 这会导致基本操作中非常奇怪的交互:

  1. >>> changeNum(5, 20) 
  2. >>> 5 - 7 == 13 
  3. True 
  4. >>> 5 - 7 - 8 == 5 
  5. True 

如果您真的想伤害您的大脑,请弄乱另外几个数字并做一些数学运算:

  1. >>> changeNum(29, 100) 
  2. >>> changeNum(5, 20) 
  3. >>> changeNum(120, 200) 
  4. >>> 5 + 9100 
  5. >>> 5 + 9 + 5200 
  6. >>> 5 + 9 + 5 + 5220 
  7. >>> (5 + 9) * 52000 

您还可以制作一个非常令人困惑的无限while循环:

  1. >>> while 5 // 4 == 5: 
  2. ... pass 
  3. ... # Do loop stuff 

崩溃的Python

我们现在去钓大鱼吧; 我们已经解决了其他不重要的数字,但是如果我们改变1会发生什么?

  1. >>> changeNum(1, 2) 
  2. >>> 1 
  3. Segmentation fault (core dumped) 

它崩溃了。 这不足为奇,因为1是非常重要的计算中使用的非常重要的数字。 我不确定更改1是否会影响True,但如果确实如此,我会想像一下后果。

最后的话

Python很棒,尽管这些交互很难看,但我仍然觉得它们很酷,希望您也这样做。 您可以用它来恶作剧的朋友或同事,让他们发疯,因为他们试图找出5不是5的原因。

没有这篇Reddit帖子和令人惊叹的GitHub存储库,这篇文章是不可能的,我极力鼓励将它们检出。

感谢您与我共度这段时光。

评论关闭