最近看<python 核心編程2>的時候,講到可變類型和不可變類型的時候,使用id(),至於id()函數返回值,書中只是說與分配的內存地址有密切關係,那麼是什麼關係呢?
請看下面實驗結果:
dotheright@dotheright:~$ python
Python 2.7.6 (default, Jun 22 2015, 18:00:18)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> x=12
>>> id(x)
144705580
>>> hex(144705580)
'0x8a0082c'
>>>
目前變量有了是x,id的返回值也有了是'0x8a0082c' 他們之間有什麼關係呢?
除非你是地址設置的是實模式(部分十分簡單的嵌入式系統是這樣),否則我們不能直接看地址裏面的內容.我們需要先找到這個python shell 對應的進程,然後在這個進程中看地址對應的內容.
dotheright@dotheright:~$ ps -h
2210 pts/0 Ss+ 0:00 /bin/bash
5876 pts/21 Ss 0:00 bash
5892 pts/21 S+ 0:00 python
5973 pts/22 Ss 0:00 bash
6160 pts/22 R+ 0:00 ps -h
我這個系統上進程Id是5892,進入超級用戶,gdb 調試這個進程
#gdb attach --pid 5892
......
(gdb) print *(int *)0x8a0082c
$1 = 14
這個值是14 不是,12 ,所以可以確定的是 id的返回值如果作爲地址,裏面不是直接存的id對應的內容,那麼Id對應的內容存在什麼地方了呢?
(gdb) x /16x 0x8a0082c
0x8a0082c: 0x0000000e 0x08334ba0 0x0000000c 0x00000010
0x8a0083c: 0x08334ba0 0x0000000b 0x00000011 0x08334ba0
0x8a0084c: 0x0000000a 0x0000000e 0x08334ba0 0x00000009
0x8a0085c: 0x00000025 0x08334ba0 0x00000008 0x00000011
0x0000000c的值是12 ,很可能是id對應內容的存儲位置.我可以再驗證一把,
退出GDB,否則python shell 不能操作,
>>> x=0xffee
>>> id(x)
144883596
>>>
(gdb) x /16x 144883596
0x8a2bf8c: 0x00000001 0x08334ba0 0x0000ffee 0x00000000
0x8a2bf9c: 0x08a2bfc8 0x08a7c698 0x00000000 0x08a2bfd4
0x8a2bfac: 0x00001808 0x00000001 0x08334ba0 0x0000ffff
0x8a2bfbc: 0x00000001 0x08334ba0 0x08a2bf8c 0x00000000
(gdb)
由此我們可以看到 對於python中 int 類型的變量, 其Id = (int *)&x-2 ;
複雜類型,需要進一步探究.