class LockGuard(object):
def __init__(self, mutex):
self.mutex = mutex
self.mutex.acquire()
def __del__(self):
self.mutex.release()
在代码中,每次使用此
时都会收到警告def do_something(self)
locker = LockGuard(self.mutex)
// do something on the data
return outcome
我知道c ++编译器优化了未使用的变量,我想知道python是否会这样做?因此,请删除对数据的锁定。
答案 0 :(得分:10)
linter 应对此提出错误。因为管理上下文的正确方法是使用context manager。
with LockGuard():
# do stuff
将有关如何获取和释放锁定的实施细节分别放入LockGuard.__enter__
和LockGuard.__exit__
。
您不应该依赖__init__
和__del__
,因为__del__
不可靠。
我知道C ++编译器会优化未使用的变量,我想知道Python是否也会这样做?因此,请删除对数据的锁定。
Python不会这样做。有一些窥视孔优化,但没有像完全从范围中删除对象那么激烈。一旦实例的引用计数降为零(即一旦locker
名称超出范围),就应该将其删除,但是当发生这种情况时,无法保证实现甚至没有保证会调用自定义__del__
。
答案 1 :(得分:5)
您滥用__del__
方法。
请参阅the documentation for object.__del__
中的巨大警告栏:
警告:由于岌岌可危的情况,调用了
__del__()
种方法, [...] 。特别是:当执行任意代码时,可以调用
- 在解释器关闭期间可以执行
__del__()
,包括来自任意线程。 如果__del__()
需要锁定或调用任何其他阻塞资源,它可能会死锁,因为执行__del__()
时被中断的代码可能已占用资源。 < em>(强调我的)__del__()
。 [...]
正确的解决方案是实现context manager并使用with
语句进入和退出。
答案 2 :(得分:2)
这个简单的功能
def f():
a = 3
答案是否定的:没有优化;用
拆解from dis import dis
dis(f)
给出:
6 0 LOAD_CONST 1 (3)
3 STORE_FAST 0 (a)
6 LOAD_CONST 0 (None)
9 RETURN_VALUE
所以分配a
(......然后不以任何方式使用)。你可以检查一下你的代码;我很确定它会是一样的。
如何修复代码:我同意this answer。