python垃圾回收及闭包异常抛出

#coding: gbk
import sys

def foo(func):
    def bar(*args, **kwargs):
        ret = func(*args, **kwargs)
        print "done func"
        return ret
    return bar

class Obj(object):

    def __init__(self):
        print self
    def __del__(self):
        print "__del__", self



@foo
def f(x=2):
    obj = Obj()
    1/0


@foo
def f2(x=2):
    obj = Obj()

def ff():
    try:
        f(x=3)
    except:
        #raise
        excList = sys.exc_info()
        print excList[0],(excList[1]),excList[2]
        print "......"
        f2(x=4)

def fff():
    ff()
    print "fffffffff"
#fff()

import threading
import time

t = threading.Thread(target=fff)
t.start()


while 1:
    time.sleep(5)
    break




输出结果:


C:\>python Closure.py
<__main__.Obj object at 0x025D1CF0>
integer division or modulo by zero ack object at 0x025D3B70>
......
<__main__.Obj object at 0x025D1D10>
__del__ <__main__.Obj object at 0x025D1D10>
done func
fffffffff
__del__ <__main__.Obj object at 0x025D1CF0>


根据打印结果,我们知道0x025D1CF0在方法执行完,没有任何引用的情况下,并没有回收,屏蔽1/0这个报错,就如0x025D1D10一样,里面回收。

这里做两个猜测:

1.   抛异常,有异常方法对象存在于traceback中,引用计数器并不是0(这种情况还是可以回收,但是不是立马)

2.   垃圾回收机制中,循环回收并不是及时执行,但是引用计数器是及时回收的(一旦明确引用计数为0,立马回收)


因此注意__del__使用需格外小心,特别是框架中如连接回收,建议使用弱应用




你可能感兴趣的:(python)