微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Python,Windows和多处理

我有一个最初构建在Linux上的Python程序,我现在正试图移植到Windows.我在一个包含所有依赖项的虚拟环境中运行程序(我的程序安装为带有pip install的轮子–find-links wheels my_module).该计划启动

(venv) C:\>venv\Scripts\python.exe -m base_module.Launcher arg1 arg2

base_module加载我的模块,由所提供的参数解释,他的相关代码是:

from multiprocessing.managers import SyncManager
import OtherCustomClass

class BaseModule(object):
    def __init__(self, arg1, arg2):
        self.manager = SyncManager()
        self.manager.start(ignore_interrupt)

def main(argv=None):
    ret = -1
    try:
        basmod = BaseModule(argv[0], argv[1])
        ret = basmod.run()
    except Exception, err:
        print("error: " + str(err))
        print(traceback.format_exc())
    return ret

if __name__ == "__main__":
    exitCode = main(sys.argv[1:])
    sys.exit(exitCode)

这在Linux中运行良好,但在Windows上我得到以下异常:

Traceback (most recent call last):
    File "<string>", line 1, in <module>
    File "C:\Python27\Lib\multiprocessing\forking.py", line 380, in main
      prepare(preparation_data)
    File "C:\Python27\Lib\multiprocessing\forking.py", line 505, in prepare
      '__parents_main__', file, path_name, etc
    File "build/bdist.linux-x86_64/egg/base_module/BaseModule.py", line 2, in <module>
ImportError: No module named OtherCustomClass
exception in main:
Traceback (most recent call last):
    File "build/bdist.linux-x86_64/egg/base_module/BaseModule.py", line 12, in main
    File "build/bdist.linux-x86_64/egg/base_module/BaseModule.py", line 7, in __init__
    File "C:\Python27\Lib\multiprocessing\managers.py", line 528, in start
        self._address = reader.recv()
EOFError

一个EOFError是由SyncManager中的分叉意外提前终止引起的,其中真正的错误是无法导入OtherCustomClass.我已经确认了OtherCustomClass存在于venv / lib / site-packages中的base_module文件夹中,并且当我首先启动模块时不会发生此错误,因为Python永远不会到达main()或init中的指令,如果脚本不能编译.

我做了一些研究,我知道这个问题已经打击了其他人(通常使用第三方库,他们在没有发布解决方案的情况下解决了这个问题).它似乎追溯到Windows缺乏fork()和python在Windows上处理多处理 – 另见http://docs.python.org/library/multiprocessing.html#windows.但我对如何解决这个问题感到茫然.

这是最新的Python 2.7分支(2.7.8),在Windows 7 x64上运行.

解决方法:

您可以通过对OtherCustomClass使用绝对导入来解决此问题:

from base_module import OtherCustomClass

我不确定为什么,但似乎当多处理产生一个新进程并导入你的__main__时,它无法处理你用于OtherCustomClass的隐式相对导入.如果从base_module显式导入它,它可以正常工作.我的猜测是,生成的子进程不被识别为base_module包的一部分,因此隐式导入失败,但这只是猜测.

请注意0​​7000(它们完全从Python 3中删除),因此切换到绝对导入并不是一件坏事.

另外值得注意的是,在Python 3.4上进行显式相对导入是可行的:

from . import OtherCustomClass

但它在Python 2.7上失败了:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "C:\python27\lib\multiprocessing\forking.py", line 380, in main
    prepare(preparation_data)
  File "C:\python27\lib\multiprocessing\forking.py", line 495, in prepare
    '__parents_main__', file, path_name, etc
  File "C:\Users\oreild1\Desktop\base_module\Launcher.py", line 5, in <module>
    from . import OtherCustomClass
ValueError: Attempted relative import in non-package
error:
Traceback (most recent call last):
  File "C:\Users\oreild1\Desktop\base_module\Launcher.py", line 18, in main
    basmod = BaseModule(argv[0], argv[1])
  File "C:\Users\oreild1\Desktop\base_module\Launcher.py", line 10, in __init__
    self.manager.start()
  File "C:\python27\lib\multiprocessing\managers.py", line 528, in start
    self._address = reader.recv()
EOFError

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐