Python奇怪的多处理与变量名称

Tan*_*Woo 7 python multiprocessing

一个简单的例子:

#!/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()
Run Code Online (Sandbox Code Playgroud)

与错误做时运行current_process__del__:

Constructor ... MainProcess
Exception AttributeError: "'NoneType' object has no attribute 'current_process'" in <bound method Klass.__del__ of <__main__.Klass object at 0x7f5c34e52090>> ignored
Run Code Online (Sandbox Code Playgroud)

如果我更改变量名称:

als = Klass()
Run Code Online (Sandbox Code Playgroud)

它得到了正确的结果:

Constructor ... MainProcess
... Destructor MainProcess
Run Code Online (Sandbox Code Playgroud)

我尝试了很多变量名,有些没问题,有些错误.

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

unu*_*tbu 9

代码提出来了

AttributeError: "'NoneType' object has no attribute 'current_process'"
Run Code Online (Sandbox Code Playgroud)

如果在multiprocessing删除之前kls删除全局变量.通常,删除对象的顺序是不可预测的.但是,根据文档:

从版本1.5开始,Python保证在删除其他全局变量之前,从其模块中删除名称以单个下划线开头的全局变量; 如果不存在对此类全局变量的其他引用,这可能有助于确保在__del__()调用方法时导入的模块仍然可用.

因此,如果您为实例命名_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()
Run Code Online (Sandbox Code Playgroud)

产量

Constructor ... MainProcess
... Destructor MainProcess
Run Code Online (Sandbox Code Playgroud)

del在删除模块之前调用确保方法的其他方法包括

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