我当时是看的: https://benkurtovic.com/2015/01/28/python-object-replacement.html
用的是 ctypes.memmove;
ctypes.memmove(id(a), id(2), object.__sizeof__(a))
虽然可以改变值, 但经常 segmentation fault
1
sivacohan 2017-03-24 14:55:53 +08:00 via Android
求解答,这个真不知道。
不过 1 是不可变对象,启动的时候进程就已经分配好了地址。 这么变, a=1 , b=1 , id(a) ==id(b)==id(1) 把 1 变了, b 不是也变了? |
2
Lycnir 2017-03-24 15:05:47 +08:00
请指教~
|
3
kgf0ry 2017-03-24 16:39:04 +08:00 via Android
是否可以转化为列表。利用列表下标去做呢?只是一点想法求赐教
|
4
kindjeff 2017-03-24 17:18:49 +08:00 via iPhone
楼主跑路了
|
5
EchoUtopia 2017-03-24 17:26:26 +08:00
1也是一个普通的 python 对象,改变 1 这个值就行了吧
|
6
shenxgan 2017-03-24 17:30:39 +08:00
楼主快说,请你吃瓜
|
7
introom 2017-03-24 17:32:07 +08:00 via Android
假定是 cpython,你要这样改变,那得从 c 层面。
ctypes 可以试试,或者干脆写个 c module. |
8
EchoUtopia 2017-03-24 17:38:48 +08:00
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 |
9
Muninn 2017-03-24 17:39:04 +08:00
感觉没办法吧
|
10
EchoUtopia 2017-03-24 17:39:40 +08:00
|
11
weyou 2017-03-24 17:42:26 +08:00 via Android
如果能改,那就把常量 1 所在地址指向的值改掉了,那 1 就不是 1 了, python 中所有引用到 1 的地方就是你的新值了。所以 Python 不可能有这么一个途径来实现你的要求
|
12
weyou 2017-03-24 17:48:17 +08:00 via Android
@EchoUtopia ctype 是一个另类,相当于直接调用 c 语言使用地址赋值了
|
13
EchoUtopia 2017-03-24 17:50:18 +08:00
@weyou #12 楼主的要求只是简单的不改变a的地址,改变a的值,所以改变1
的地址就行了呗 |
14
EchoUtopia 2017-03-24 17:53:26 +08:00
@EchoUtopia #13 说错了,改变1的值
|
15
a87150 2017-03-24 17:53:34 +08:00
@EchoUtopia 感觉 ctypes 真厉害,虽然我不会用
|
16
EchoUtopia 2017-03-24 18:03:31 +08:00
@a87150 #15 我也不会用,只是很久以前解析网络包用过一次,早都忘了,感觉很高大上
|
17
weyou 2017-03-24 18:03:44 +08:00 via Android
@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 版本之间整数对象结构有差异。 |
18
EchoUtopia 2017-03-24 18:07:15 +08:00
我也不清楚
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] |
19
zhanglintc 2017-03-24 18:24:12 +08:00
楼主快出来, 胃口已经吊起来了
|
20
glasslion 2017-03-24 18:57:25 +08:00
@EchoUtopia
You shouldn't want to. This isn't Ruby, heathen. ---------------------------------------------------------------------------- reddit 上第一条吐槽把 Ruby 黑出翔了 |
22
aploium 2017-03-24 20:25:11 +08:00
歪个楼, 如果只是要 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 本身实在是太灵活了, 你甚至可以在运行时去魔改语法树, 所以我也不知道有没有什么黑科技能实现这个东西 |