我观察到在异常之后我有一个没有调用构造函数的对象,这会导致锁定。改善这种情况的最佳方法是什么?在一个except块中调用del是解决方案吗?
b=BigHash(DB_DIR, url)
meta = bdecode(b.get())
return meta
b持有一个在销毁时释放的锁(它是一个C ++对象) b.get()抛出异常。
答案 0 :(得分:3)
无论如何,您都希望释放锁定 - 无论是否抛出异常。在这种情况下,最好在finally:
子句中释放锁定/删除b:
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
您还可以使用上下文管理器 - http://docs.python.org/library/stdtypes.html#typecontextmanager。只需添加代码即可释放BigHash.__exit__
函数中的锁定,该函数将在以下代码中保留with
块后调用:
with BigHash(DB_DIR, url) as b:
meta = bdecode(b.get())
return meta
答案 1 :(得分:1)
您需要执行以下操作以确保b处于解锁状态
b=BigHash(DB_DIR, url)
try:
meta = bdecode(b.get())
return meta
finally:
#unlock b here
如果BigHash可以作为上下文工作,那么更简洁的方法是,所以你可以编写
with b as BigHash(DB_DIR, url):
meta = bdecode(b.get())
return meta
您可能需要向BigHash添加一些代码,以使其作为上下文工作
答案 2 :(得分:0)
在姓名上调用del
是你从未做过的事情。 调用del
并不保证对底层对象会发生什么有用。您永远不应该依赖__del__
方法来处理您需要发生的事情。
del
只能删除一个对象的引用,这可能会让你在没有思考的情况下做出更多的事情时感到困惑。因此,del
对于清理命名空间非常有用,而不是用于控制对象的生命周期,而它甚至不是很好 - 控制名称生命周期的正确方法就是放置它在一个函数中,让它超出范围或将其放在一个块中。
您需要让BigHash
能够使用release
或unlock
或close
方法明确释放锁 。如果要将其与上下文管理器(with
)一起使用,则可以定义__exit__
,这将在可预测的有用时间进行调用。