python中的id() 函数深度解剖
2016-05-18 00:06
483 查看
最近看<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 ;
复杂类型,需要进一步探究.
请看下面实验结果:
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 ;
复杂类型,需要进一步探究.
相关文章推荐
- Python爬虫学习资料书籍推荐
- Python文件迭代的用法实例教程
- Twitter的分布式自增ID算法Snowflake实现分析及其Java、Php和Python版
- Python实战:爬虫的基础
- Python performance
- PySide——Python图形化界面
- Python 代码性能优化
- python匹配ip正则
- python 基于次世代验证码识别系统的小demo
- 发现使用python+tushare做量化交易 其实不是很难
- kombu------python的消息库
- python 安装 cairo
- 步步学习之用python实战机器学习1-kNN (K-NearestNeighbors)算法(a)
- 简单的python爬取网页字符串内容并保存
- python一些内建函数(map,zip,filter,reduce,yield等)
- Python之常用模块(待更新)
- Tornado X MVC
- [Python笔记]第九篇:re正则表达式
- python
- python学习笔记5—数据类型转换