我正在编写一个使用文件路径导入模块的程序,其函数为imp.load_source(module_name,module_path)
。当我尝试将对象从此模块传递到Process
时,它似乎会导致问题。
一个例子:
import multiprocessing
import imp
class MyProcess(multiprocessing.Process):
def __init__(self,thing):
multiprocessing.Process.__init__(self)
self.thing=thing
def run(self):
x=self.thing
if __name__=="__main__":
module=imp.load_source('life', 'C:\\Documents and Settings\\User\\workspace\\GarlicSim\\src\\simulations\\life\\life.py')
thing=module.step
print(thing)
p=MyProcess(thing)
p.start()
注意:要使此代码“正常工作”,您必须将我给imp.load_source
的参数替换为其他内容:它必须是您计算机上的某些Python文件,最好不在同一文件夹中。然后,在thing=module.step
中,而不是将某个随机函数或类放入.py
文件中。
我得到以下追溯:
<function step at 0x00D5B030>
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "C:\Python26\lib\multiprocessing\forking.py", line 342, in main
self = load(from_parent)
File "C:\Python26\lib\pickle.py", line 1370, in load
return Unpickler(file).load()
File "C:\Python26\lib\pickle.py", line 858, in load
dispatch[key](self)
File "C:\Python26\lib\pickle.py", line 1090, in load_global
klass = self.find_class(module, name)
File "C:\Python26\lib\pickle.py", line 1124, in find_class
__import__(module)
ImportError: No module named life
那我该怎么办?
修改
我在Win XP上使用Python 2.6.2c1。
答案 0 :(得分:1)
由于将导入代码放入主块,可能无法正常工作。 下面的代码适用于Windows XP,Python 2.6。然后生命模块也将在新进程中导入。
import multiprocessing
import imp
class MyProcess(multiprocessing.Process):
def __init__(self,thing):
multiprocessing.Process.__init__(self)
self.thing=thing
def run(self):
print("Exiting self.thing")
self.thing()
print("Finished")
life=imp.load_source('life', r'd:\temp5\life.py')
if __name__=="__main__":
p=MyProcess(life.step)
p.start()
答案 1 :(得分:-1)
test.py
:
import multiprocessing
import imp
class MyProcess(multiprocessing.Process):
def __init__(self,thing):
multiprocessing.Process.__init__(self)
self.thing=thing
def run(self):
print 'running...', self.thing()
if __name__=="__main__":
module=imp.load_source('life', '/tmp/life.py')
thing=module.step
print(thing)
p=MyProcess(thing)
p.start()
life.py
上的 /tmp
:
def step():
return 'It works!'
正在运行test.py
:
$ python test.py
<function step at 0xb7dc4d4c>
running... It works!
我刚刚测试过并且它有效,所以你必须做错其他的事情。请编辑您的问题并粘贴无效的实际代码。
我使用默认python的ubuntu Jaunty 9.04(Python 2.6.2 release26-maint,2009年4月19日,01:56:41)。不知道你的问题是否仅限于Windows,因为我没有可用于测试的窗口。
这就是使用导入路径进行修改是一个坏主意的原因。您永远无法适应所有平台/环境,您的用户可能会生气。最好只使用python方式查找模块,这是通过将模块放在python模块搜索路径上。这将在所有地方持续发挥作用。
答案 2 :(得分:-1)
我刚刚完成以下操作,在XP上运行Python 2.5 ...
D:\Experiments\ModuleLoading\test.py
import imp
if __name__=="__main__":
module=imp.load_source('life', r'D:\Experiments\ModuleLoading\somefolder\life.py')
thing=module.step
print(thing)
D:\Experiments\ModuleLoading\somefolder\step.py
def step():
return 'It works!'
...并运行脚本给出:
D:\jcage\Projects\Experiments\ModuleLoading>test.py
<function step at 0x00A0B470>
...首先尝试一下,确保模块无需多处理即可加载?
[编辑] 好的,这绝对是导入分叉流程的问题。有some bits and pieces in the documentation which are specific to windows:
更多可挑选性
确保Process .__ init __()的所有参数都是可选的。这尤其意味着绑定或未绑定的方法不能直接用作Windows上的目标参数 - 只需定义一个函数并使用它。 此外,如果您继承Process,那么确保在调用Process.start()方法时可以选择实例。
全局变量
请记住,如果在子进程中运行的代码尝试访问全局变量,那么它看到的值(如果有)可能与Process.start时父进程中的值不同( ) 被称为。 但是,只是模块级常量的全局变量不会引起任何问题。
安全导入主模块
确保新的Python解释器可以安全地导入主模块,而不会导致意外的副作用(例如启动新进程)。
[Edit2] 您有什么理由不能在此过程中进行导入?我认为问题在于,当您启动新进程时,它不会在相同的地址空间中运行,因此尝试访问原始线程中的函数将无法正常工作。
您可以为D:\Experiments\ModuleLoading\test.py
执行此操作:
from multiprocessing import Process
import imp
class MyProcess(Process):
def __init__(self):
Process.__init__(self)
def run(self):
print 'run called...'
module=imp.load_source('life', r'D:\Experiments\ModuleLoading\somefolder\life.py')
print 'running...', module.step()
if __name__=="__main__":
p=MyProcess()
p.start()