令变量 a = 1, 如何在不改变 a 的内存地址的前提下, 即 id(a) 不变, 改变 a 的值.
我无聊翻文档看到的...
我无聊翻文档看到的...
我当时是看的: https://benkurtovic.com/2015/01/28/python-object-replacement.html
用的是 ctypes.memmove;
ctypes.memmove(id(a), id(2), object.__sizeof__(a))
虽然可以改变值, 但经常 segmentation fault
|
sivacohanMar 24, 2017 via Android
1
求解答,这个真不知道。
不过 1 是不可变对象,启动的时候进程就已经分配好了地址。 这么变, a=1 , b=1 , id(a) ==id(b)==id(1) 把 1 变了, b 不是也变了? |
|
LycnirMar 24, 2017
2
请指教~
|
|
kgf0ryMar 24, 2017 via Android
3
是否可以转化为列表。利用列表下标去做呢?只是一点想法求赐教
|
|
kindjeffMar 24, 2017 via iPhone
4
楼主跑路了
|
|
EchoUtopiaMar 24, 2017
5
1也是一个普通的 python 对象,改变 1 这个值就行了吧
|
|
shenxganMar 24, 2017
6
楼主快说,请你吃瓜
|
|
introomMar 24, 2017 via Android
7
假定是 cpython,你要这样改变,那得从 c 层面。
ctypes 可以试试,或者干脆写个 c module. |
|
EchoUtopiaMar 24, 2017
8
import ctypes
a = 1 print(a, id(a)) def deref(addr, typ): return ctypes.cast(addr, ctypes.POINTER(typ)) deref(id(1), ctypes.c_int)[6] = 100 print (a, id(a)) 注: python3 |
|
MuninnMar 24, 2017
9
感觉没办法吧
|
|
EchoUtopiaMar 24, 2017
10
|
|
weyouMar 24, 2017 via Android
11
如果能改,那就把常量 1 所在地址指向的值改掉了,那 1 就不是 1 了, python 中所有引用到 1 的地方就是你的新值了。所以 Python 不可能有这么一个途径来实现你的要求
|
|
weyouMar 24, 2017 via Android
12
@EchoUtopia ctype 是一个另类,相当于直接调用 c 语言使用地址赋值了
|
|
EchoUtopiaMar 24, 2017
13
@weyou #12 楼主的要求只是简单的不改变a的地址,改变a的值,所以改变1
的地址就行了呗 |
|
EchoUtopiaMar 24, 2017
14
@EchoUtopia #13 说错了,改变1的值
|
|
a87150Mar 24, 2017
15
@EchoUtopia 感觉 ctypes 真厉害,虽然我不会用
|
|
EchoUtopiaMar 24, 2017
16
@a87150 #15 我也不会用,只是很久以前解析网络包用过一次,早都忘了,感觉很高大上
|
|
weyouMar 24, 2017 via Android
17
@EchoUtopia 我在手机上的 termux/python3.5 上试了下,发生错误:
>>> ctypes.cast(id(1), ctypes.POINTER(ctypes.c_int))[6]=100 >>> id(a) Fatal Python error: non-string found in code slot Current thread 0x0000007fb60c2fe8 (most recent call first): Aborted (core dumped) 但理论上是可行的,估计 Python 版本之间整数对象结构有差异。 |
|
EchoUtopiaMar 24, 2017
18
我也不清楚
import ctypes a = 1 print(a, id(a)) def deref(addr, typ): return ctypes.cast(addr, ctypes.POINTER(typ)) deref(id(1), ctypes.c_int)[6] = 100 print (a, id(a)) import sys print(sys.version) 输出: 1 10771520 100 10771520 3.4.2 (default, Oct 8 2014, 10:45:20) [GCC 4.9.1] |
|
zhanglintcMar 24, 2017
19
楼主快出来, 胃口已经吊起来了
|
|
glasslionMar 24, 2017
20
@EchoUtopia
You shouldn't want to. This isn't Ruby, heathen. ---------------------------------------------------------------------------- reddit 上第一条吐槽把 Ruby 黑出翔了 |
|
aploiumMar 24, 2017
22
歪个楼, 如果只是要 id(a) 不变的话, 覆盖掉 id() 就行
如果要正经做的话可能挺难的 看一个例子 ```python >>> a=1 >>> b=1 >>> id(a)==id(b)==id(1) True ``` python 内部会预创建一些小整数, 之后所有用到这些小整数的地方都应用同一个内存实例 再看一个比较大的数 ```python >>> a=500000 >>> b=500000 >>> id(a) 1658156658384 >>> id(b) 1658161244880 >>> id(500000) 1658161245136 ``` 所以如果不使用某些黑魔法的话, 要做到这样, 可能会导致所有的 1 都发生改变 当然...因为 python 本身实在是太灵活了, 你甚至可以在运行时去魔改语法树, 所以我也不知道有没有什么黑科技能实现这个东西 |