Kel*_*ndy 101 python cpython python-internals
Pythonint是封装实际数值的对象。我们可以修改这个值吗,例如将对象的值设置1为 2?那么这就1 == 2变成了True?
Kel*_*ndy 162
我们可以。但不要在家里这样做。说真的,该1对象在很多地方都使用,我不知道这可能会破坏什么以及可能对您的计算机产生什么影响。我拒绝承担所有责任。但我发现了解这些事情很有趣。
该id函数为我们提供了内存地址,而该ctypes模块让我们可以处理内存:
import ctypes\n\nctypes.memmove(id(1) + 24, id(2) + 24, 4)\n\nprint(1 == 2)\n\nx = 40\nprint(x + 1)\nRun Code Online (Sandbox Code Playgroud)\n输出:
\nimport ctypes\n\nctypes.memmove(id(1) + 24, id(2) + 24, 4)\n\nprint(1 == 2)\n\nx = 40\nprint(x + 1)\nRun Code Online (Sandbox Code Playgroud)\n在线尝试一下!。我在那里尝试过,因为无论如何,这些网站都必须受到保护,免受我们的黑客攻击。
\n更多解释/分析:
\n将memmove值从2对象复制到1对象中。它们的大小各为 28 个字节,但我跳过了前 24 个字节,因为那是对象的引用计数、类型地址和值大小,我们也可以查看/验证:
import ctypes, struct, sys\n\nx = 1\ndata = ctypes.string_at(id(x), 28)\nref_count, type_address, number_of_digits, lowest_digit = \\\n struct.unpack(\'qqqi\', data)\n\nprint(\'reference count: \', ref_count, sys.getrefcount(x))\nprint(\'type address: \', type_address, id(type(x)))\nprint(\'number of digits:\', number_of_digits, -(-x.bit_length() // 30))\nprint(\'lowest digit: \', lowest_digit, x % 2**30)\nRun Code Online (Sandbox Code Playgroud)\n输出(在线尝试!):
\nTrue\n42\nRun Code Online (Sandbox Code Playgroud)\n引用计数因调用而增加getrefcount,但我不知道为什么增加了 3。无论如何,除了我们之外还有约 134 个对象引用了该1对象,而且我们可能会搞乱所有这些对象,所以...真的不知道不要在家尝试这个。
“数字”指的是 CPython 如何将ints 存储为以 2 30为基数的数字。例如,x = 2 ** 3000有 101 个这样的数字。x = 123 ** 456为了更好的测试而输出:
import ctypes, struct, sys\n\nx = 1\ndata = ctypes.string_at(id(x), 28)\nref_count, type_address, number_of_digits, lowest_digit = \\\n struct.unpack(\'qqqi\', data)\n\nprint(\'reference count: \', ref_count, sys.getrefcount(x))\nprint(\'type address: \', type_address, id(type(x)))\nprint(\'number of digits:\', number_of_digits, -(-x.bit_length() // 30))\nprint(\'lowest digit: \', lowest_digit, x % 2**30)\nRun Code Online (Sandbox Code Playgroud)\n
Hol*_*way 39
在 Python 2 中,有一种更简单的方法 -True并且False不受保护,因此您可以将内容分配给它们。
>>> True = False
>>> (1 == 2) is True
True
Run Code Online (Sandbox Code Playgroud)
dan*_*n04 11
如果您不想弄乱缓存int或对象的实际内容,您可以像这样bool伪造:1 == 2
>>> import builtins
>>> import sys
>>>
>>> def displayhook(value):
... if value is False:
... value = True
... elif value is 1:
... value = 2
... text = repr(value)
... sys.stdout.write(text)
... sys.stdout.write('\n')
... builtins._ = value
...
<stdin>:4: SyntaxWarning: "is" with a literal. Did you mean "=="?
>>> sys.displayhook = displayhook
>>> 1
2
>>> 1 == 2
True
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8373 次 |
| 最近记录: |