python 引用,拷贝,对象回收,弱引用
2011-12-13 18:50
721 查看
引用
python中,在对对象赋值,参数传递,函数返回等等, 都是引用传递的. 直接copy个例子来【1】:a = [1, 2, 3] b = a b.append(5) print a, b
输出结果为:
[1, 2, 3, 5] [1, 2, 3, 5]
上面的结果有助于理解引用的实际情况。 具体查看一个对象的引用数,可以使用sys.getrefcount(ojb)获取,但这个函数有点邪恶,有时似乎并不给出正确的结果,正常来说获取的值都比你想要的大,一般是大1,因为给这个函数传参数也算一个引用。但有时会大得离谱,来例子:
import sys a = "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 = A if __name__ = ="__main__": foo()
运行结果为:
Object with id 10462448 born here.
Object with id 10462832 born here.
在构造一个类时,__init__会被自动调用;在进行对象回收时,__del__会被调用。很清楚的看到对象只是被创建了,而没有被回收,原因很简单,A和B的由于互相引用,他们的引用次数是不可能为0的,自然被回收也是不可能的了。这是,就应该考虑弱引用了。
弱引用
这是相对上面“引用”的一个概念,主要不同体现在对象回收时,上面我只提到当引用数为0,对象就会自动回收。其实还有另外一种情况,当自由只有对对象的弱引用时,对象也是会被回收。直接上代码,对上例做出一些修改:import weakref 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 = 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
<socket._socketobject instance at 007B4A94>
>>> ref
<weakref at 0x81195c; to 'instance' at 0x7b4a94>
>>> ref() #调用它来访问被引用的对象
<socket.socketobject instance at 007B4A94>
2. 创建代理对象
代理对象是弱引用对象,它们的行为就像它们所引用的对象,这就便于你不必首先调用弱引用来访问背后的对象。通过weakref模块的proxy(obj[,callback])函数来创建代理对象。使用代理对象就如同使用对象本身一样:
>>> from socket import*
>>> import weakref
>>> s=socket(AF_INET,SOCK_STREAM)
>>> ref=weakref.proxy(s)
>>> s
<socket._socketobject instance at 007E4874>
>>> ref
<socket._socketobject instance at 007E4874>
>>> ref.close() #对象的方法同样工作
callback参数的目的和ref函数相同。在Python删除了一个引用的对象之后,使用代理将会导致一个weakref.ReferenceError错误:
>>> del s
>>> ref
Traceback (most recent call last):
File "<stdin>", line 1, in ?
3. getweakrefcount(obj)和getweakrefs(obj)分别返回弱引用数和关于所给对象的引用列表
参考文献:
【1】 http://blog.sina.com.cn/s/blog_5357c0af0100n2q5.html
【2】http://linhs.blog.51cto.com/370259/142846/
【3】http://longmans1985.blog.163.com/blog/static/70605475200991613556128/
相关文章推荐
- 流畅的python第八章对象引用,可变性和垃圾回收
- 基于Python对象引用、可变性和垃圾回收详解
- Python 初体验之 对象的引用和拷贝
- 流程的Python 第八章:对象引用、可变性和垃圾回收
- Python 对象引用、可变性和垃圾回收
- python3的对象引用、浅拷贝与深拷贝
- python赋值和拷贝----一切皆对象,参数皆引用
- python赋值和拷贝----一切皆对象,参数皆引用
- Python中的对象引用、浅拷贝与深拷贝
- python赋值和拷贝----一切皆对象,参数皆引用
- Python 对象的引用计数和拷贝
- Python中的可变,不可变对象;值类型,引用类型;浅拷贝,深拷贝理解
- Python:创建对象中的引用和拷贝
- python 对象拷贝——浅拷贝和深拷贝 之函数传递——值传递还是引用传递?
- 【Python】对象拷贝、对象传参、对象引用
- 【python】理解python里的赋值、引用、拷贝及作用域、内存管理、垃圾回收
- python中的对象拷贝示例 python引用传递
- python中的对象拷贝示例 python引用传递
- python赋值和拷贝----一切皆对象,参数皆引用
- Python:创建对象中的引用和拷贝