python是否优化了未使用的变量?

时间:2018-03-07 20:00:03

标签: python

对于我创建的以下类,我的linter经常会因未使用的变量警告而烦恼:

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是否会这样做?因此,请删除对数据的锁定。

3 个答案:

答案 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