博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python 引用,拷贝,对象回收,弱引用
阅读量:6258 次
发布时间:2019-06-22

本文共 2892 字,大约阅读时间需要 9 分钟。

hot3.png

引用

python中,在对对象赋值,参数传递,函数返回等等, 都是引用传递的. 直接copy个例子来【1】:

a = [1, 2, 3]b = ab.append(5)print a, b

输出结果为:

[1, 2, 3, 5] [1, 2, 3, 5]

面的结果有助于理解引用的实际情况。 具体查看一个对象的引用数,可以使用sys.getrefcount(ojb)获取,但这个函数有点邪恶,有时似乎并不给出正确的结果,正常来说获取的值都比你想要的大,一般是大1,因为给这个函数传参数也算一个引用。但有时会大得离谱,来例子:

import sysa = "a"sys.getrefcount(a)

在我的机器上,输出结果尽然为14,网络遛了一圈,有人说是python内部对“a”这个对象进行了应用。好吧!就这样理解把,有高见的可以留言告我一下!

拷贝【1】

拷贝主要有两种拷贝,分别以copy模块中的两个函数copy和deepcopy为代表。其中,前者复制对象本身,但对于对象中得元素,还是会使用的原本引用,copy个例子来:

list_of_lists = [ ['a'], [1, 2], ['z', 23] ]copy_lol = copy.copy(lists_of_lists)copy_lol[1].append('boo')print list_of_lists, copy_lol

输出结果为:

[['a'], [1, 2, 'boo'], ['z', 23]] [['a'], [1, 2, 'boo'], ['z', 23]]

考到第二个元素的情况了 把!用的还是引用。要想全部对对象本省进行拷贝,就得使用deepcopy了。

对象回收

Python使用了垃圾回收器来自动销毁那些不再使用的对象。当对某个对象的引用计数为0时, Python能够安全地销毁这个对象。表面上看来,在使用C或者C++时经常会碰到的内存泄露问题似乎也就解决了,但实际的情况是,请你小心!再copy个例子来【2】:

class LeakTest(object):   def __init__(self):     print 'Object with id %d born here.' % id(self)   def __del__(self):     print 'Object with id %d dead here.' % id(self)def foo():   A = LeakTest()   B = LeakTest()   A.b = B   B.a = Aif __name__ = ="__main__":   foo()

运行结果为:

Object with id 10462448 born here.Object with id 10462832 born here.

在构造一个类时,__init__会被自动调用;在进行对象回收时,__del__会被调用。很清楚的看到对象只是被创建了,而没有被回收,原因很简单,A和B的由于互相引用,他们的引用次数是不可能为0的,自然被回收也是不可能的了。这是,就应该考虑弱引用了。

弱引用

这是相对上面“引用”的一个概念,主要不同体现在对象回收时,上面我只提到当引用数为0,对象就会自动回收。其实还有另外一种情况,当自由只有对对象的弱引用时,对象也是会被回收。直接上代码,对上例做出一些修改:

import weakrefclass LeakTest(object):   def __init__(self):     print 'Object with id %d born here.' % id(self)   def __del__(self):     print 'Object with id %d dead here.' % id(self)def foo():   A = LeakTest()   B = LeakTest()   A.b = weakref.proxy(B)   B.a = weakref.proxy(A)if __name__ = ="__main__":   foo()

运行结果为:

Object with id 28637456 born here.Object with id 29402736 born here.Object with id 28637456 dead here.Object with id 29402736 dead here.

OK了,对象被正常回收了!最后简单解说wekref中得几个函数【3】:

1.创建弱引用:

你可以通过调用weakref模块的ref(obj[,callback])来创建一个弱引用,obj是你想弱引用的对象,callback是一个可选的函数,当因没有引用导致Python要销毁这个对象时调用。回调函数callback要求单个参数(弱引用的对象)。

一旦你有了一个对象的弱引用,你就能通过调用弱引用来获取被弱引用的对象。下面的例子创建了一个对socket对象的弱引用:

>>> from socket import * >>> import weakref >>> s=socket(AF_INET,SOCK_STREAM) >>> ref=weakref.ref(s) >>> s 
>>> ref
>>> ref() #调用它来访问被引用的对象
2. 创建代理对象
代理对象是弱引用对象,它们的行为就像它们所引用的对象,这就便于你不必首先调用弱引用来访问背后的对象。通过weakref模块的proxy(obj[,callback])函数来创建代理对象。使用代理对象就如同使用对象本身一样:
>>> from socket import* >>> import weakref >>> s=socket(AF_INET,SOCK_STREAM) >>> ref=weakref.proxy(s) >>> s 
>>> ref
>>> ref.close() #对象的方法同样工作
callback参数的目的和ref函数相同。在Python删除了一个引用的对象之后,使用代理将会导致一个weakref.ReferenceError错误:
>>> del s >>> ref Traceback (most recent call last):   File "
", line 1, in ?

3. getweakrefcount(obj)和getweakrefs(obj)分别返回弱引用数和关于所给对象的引用列表

参考文献:

【1】

【2】

【3】

转载于:https://my.oschina.net/apoptosis/blog/125894

你可能感兴趣的文章
申小雨命案审理延期至3月5日 警方将翻译嫌犯口供
查看>>
自动精简配置&重复数据删除核心技术点及其经济效应探究
查看>>
cncert网络安全周报35期 境内被植入后门的政府网站112个 环比上涨24.4%
查看>>
物联网到底是不是泡沫,且看英特尔交出的答案
查看>>
IPv6太落后了:中国加速服务器援建
查看>>
安防大数据应用国家工程实验室在乌鲁木齐成立
查看>>
物理引擎中velocity的单位是个什么鬼?
查看>>
[译] 全新 Android 注入器 : Dagger 2 (二)
查看>>
为什么要评审代码?
查看>>
小程序开发前的准备工作之【深入封装Component】
查看>>
AFN3.0源码解析
查看>>
oracle的drop命令
查看>>
设计与梳理企业二级流程的路线方法
查看>>
Python正则表达式指南
查看>>
使用css3制作渐变分割线
查看>>
垃圾回收概念与算法
查看>>
IconFont 图标svg
查看>>
TFS实现需求工作项自动级联保存
查看>>
springmvc 4.x 处理json 数据时中文乱码
查看>>
nginx 重启命令
查看>>