我有一个最初build立在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上,我得到以下exception:
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中的指令,编译。
我已经做了一些研究,而且我知道这个问题已经打击了其他人(通常使用第三方库,在没有发布解决scheme的情况下解决了问题)。 它似乎追溯到Windows缺乏fork(),以及python在Windows上处理多处理 – 另见http://docs.python.org/library/multiprocessing.html#windows 。 但是我不知道如何解决这个问题。
这是最新的Python 2.7分支(2.7.8),运行在Windows 7 x64上。
您可以通过对OtherCustomClass
使用绝对导入来解决此OtherCustomClass
:
from base_module import OtherCustomClass
我不是很确定为什么,但似乎multiprocessing
产生一个新的进程,并导入您的__main__
,它不能处理您使用与OtherCustomClass
隐式相对导入。 如果你明确从base_module
导入它,它可以正常工作。 我的猜测是生成的子进程不被识别为base_module
包的一部分,所以隐式导入失败,但这只是一个猜测。
请注意, 您不应该使用隐式相对导入 (它们完全从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 = Basemodulee(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