python字典弱引用_python 引用,拷贝,对象回收,弱引用

引用

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

>>> 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)分别返回弱引用数和关于所给对象的引用列表

参考文献:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值