Python 带有变量名的奇怪多处理

Python strange multiprocessing with variable name

一个简单的例子:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import multiprocessing

class Klass(object):
    def __init__(self):
        print "Constructor ... %s" % multiprocessing.current_process().name

    def __del__(self):
        print "... Destructor %s" % multiprocessing.current_process().name


if __name__ == '__main__':
    kls = Klass()

运行 在 __del__:

中执行 current_process 时出错
Constructor ... MainProcess
Exception AttributeError: "'NoneType' object has no attribute 'current_process'" in <bound method Klass.__del__ of <__main__.Klass object at 0x7f5c34e52090>> ignored

如果我更改变量名称:

als = Klass()

它得到正确的结果:

Constructor ... MainProcess
... Destructor MainProcess

我试了很多变量名,有的可以,有的出错。

为什么不同的实例名称,会导致多处理模块在__del__中是None?

代码引发

AttributeError: "'NoneType' object has no attribute 'current_process'"

如果在删除 kls 之前删除了全局变量 multiprocessing。 通常,删除对象的顺序是不可预测的。但是,per the docs:

Starting with version 1.5, Python guarantees that globals whose name begins with a single underscore are deleted from their module before other globals are deleted; if no other references to such globals exist, this may help in assuring that imported modules are still available at the time when the __del__() method is called.

因此,如果您将实例命名为 _kls(带下划线),那么您可以放心,它的 __del__ 将在 multiprocessing 被删除之前被调用:

import multiprocessing 

class Klass(object):
    def __init__(self):
        print "Constructor ... %s" % multiprocessing.current_process().name

    def __del__(self):
        print "... Destructor %s" % multiprocessing.current_process().name


if __name__ == '__main__':
    _kls = Klass()

产量

Constructor ... MainProcess
... Destructor MainProcess

Other methods 确保在删除模块之前调用 del 方法包括

  • 使用atexit
  • 使用上下文管理器
  • 将对模块的引用保存为 Klass 的属性。