开发者

Garbage collection of object after exception

I have observed that after an exception I have an object for which constructor is not called, which causes a lock to be held. What is the best way to improve the situation? Would calling del in an except block be the solution?

b=BigHash(DB_DIR, url)
meta = bdecode(b.get())
return meta

b holds a lock which is 开发者_如何学Creleased on destruction (it's a C++ object) an exception is thrown by b.get().


No matter what, you want the lock to be released - whether or not an exception is thrown. In that case, it's probably best to release the lock/delete b in a finally: clause:

b=BigHash(DB_DIR, url)
try:
    meta = bdecode(b.get())
finally:
    del b # or whatever you need to do to release the lock
return meta

You could also use a context manager - http://docs.python.org/library/stdtypes.html#typecontextmanager. Simply add code to free the lock in the BigHash.__exit__ function, which will be called after leaving the with block in the following code:

with BigHash(DB_DIR, url) as b:
    meta = bdecode(b.get())
return meta


You need to do something like this to make sure b in unlocked

b=BigHash(DB_DIR, url)
try:
    meta = bdecode(b.get())
    return meta
finally:
    #unlock b here

A cleaner way would be if BigHash can work as a context, so you can write

with b as BigHash(DB_DIR, url):
    meta = bdecode(b.get())
    return meta

You might have to add some code to BigHash to make it work as a context though


Calling del on a name is something you prettymuch never should do. Calling del does not guarantee anything useful about what will happen to the underlying object. You should never depend on a __del__ method for something you need to happen.

del only gets rid of one reference to an object, which can be confusing when you may have made more without thinking. Therefore, del is useful for cleaning up a namespace, not for controlling the lifetime of objects, and it's not even great for that—the proper way to control a name's lifetime is to put it in a function and have it go out of scope or put it in a with block.

You need to equip BigHash with the ability to release the lock explicitly, with an release or unlock or close method. If you want to use this with a context manager (with), you can define __exit__, which will get called at a predictable, useful time.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜