python对象地址学习
2015-09-11 10:45
561 查看
一、对象地址基础知识
python内置id()函数,这个函数用于返回对象的唯一标识(identity)。对象实际内存地址为hex(id(obj)),本文我将id()和内存地址划等号。内置函数is(),用于比较两个对象的identity是否一样,举例:
(ob1 is ob2) 等价于 (id(ob1) == id(ob2))
a1 = '5' print id(a1) #输出:42662728,这个是a1指向的内存地址 a1 = '100' a2 = '100' print id(a1), id(a2) #输出:43510440 43510440 #这里python做了优化,没有为a2申请新的内存,而且将a1和a2指向相同的内存地址 s1 = 'a' * 20 s2 = 'a' * 20 print id(s1), id(s2) #输出:43997704 43997704,说明20个char情况下,python仍然将两个引用指向了相同内存地址 s1 = 'a' * 21 s2 = 'a' * 21 print id(s1), id(s2) #输出:50071400 50071568,在21个char的时候,python就没有做优化了,python为s2开辟了新的内存 # int value i1 = 10000000000000000000000..0000 i2 = 10000000000000000000000..0000 print id(i1), id(i2) #输出:39278152 39278152,两个变量大约测试650位,内存地址仍然是一样的。linux下行为不太一样,值为256后,两变量指向内存就不一样了。 # float value f1 = 250.5 f2 = 250.5 print id(f1), id(f2) #输出:37976712 37976712,但在linux上两者的地址是不一样的
二、python的不可变(immutable)变量和可变变量
python不可变类型:int,string,float,tuple#测试修改不可变变量 u = 100 print 'orgin id: %s' %id(u) u = u + 10 print 'new id : %s' %id(u) #输出: #orgin id: 38833856 #new id : 38833616 #开始的时候u指向int值100内存地址,因为int对象是不可变的,所以后面u值改为110后其实是分配了一个新的内存地址
python可变类型:object、list、set等
# a = [] print id(a) a.append('a') a.append('b') a.append('c') print id(a) #输出:50809480,50809480,可见a指向内存的地址是没有改变的
三、方法参数传递
python参数传递是:传引用方式def pass_immutable_var(v): print 'inner before id:%d, value: %d' %(id(v),v) v = 1000 print 'inner after id:%d, value: %d' %(id(v),v) if __name__ == "__main__": v = 100 print 'before id:%d, value: %d' %(id(v),v) pass_immutable_var(v) print 'after id:%d, value: %d' %(id(v),v) 输出: before id:37785280, value: 100 inner before id:37785280, value: 100 inner after id:41170808, value: 1000 after id:37785280, value: 100 可见才方法里修改了参数int值是不会修改原int值的
def pass_obj_ref(v): print 'inner before id:%d, value: %s' %(id(v),v) v.append(999) print 'inner after id:%d, value: %s' %(id(v),v) if __name__ == "__main__": v = ['100'] print 'before id:%d, value: %s' %(id(v),v) pass_obj_ref(v) print 'after id:%d, value: %s' %(id(v),v) #输出: before id:50203400, value: ['100'] inner before id:50203400, value: ['100'] inner after id:50203400, value: ['100', 999] after id:50203400, value: ['100', 999] 可见在pass_obj_ref中拿到和之前一样的对象引用,是可以修改原对象的数据的。
这个示例有个值得注意的事情,如果pass_obj_ref内只将执行“v = []”,这个是不会导致原数据被修改的,因为这个操作只是使pass_obj_ref中的v指向的新的内存地址,而原对象指针仍然指向[‘100’],这里是个容易出问题的地方,需要严重注意。
相关文章推荐
- Python动态类型的学习---引用的理解
- Python3写爬虫(四)多线程实现数据爬取
- 垃圾邮件过滤器 python简单实现
- 下载并遍历 names.txt 文件,输出长度最长的回文人名。
- install and upgrade scrapy
- Scrapy的架构介绍
- Centos6 编译安装Python
- 使用Python生成Excel格式的图片
- 让Python文件也可以当bat文件运行
- [Python]推算数独
- Python中zip()函数用法举例
- Python中map()函数浅析
- Python将excel导入到mysql中
- Python在CAM软件Genesis2000中的应用
- 使用Shiboken为C++和Qt库创建Python绑定
- FREEBASIC 编译可被python调用的dll函数示例
- Python 七步捉虫法