带有importlib模块的Python多进程
您好,带有importlib模块的Python多进程,python,python-3.x,multiprocessing,pickle,python-importlib,Python,Python 3.x,Multiprocessing,Pickle,Python Importlib,您好, 今天我将代码从线程化转移到多进程。一切似乎都正常,直到我出现以下错误: 错误 component.py 类组件(对象): def u u init u u;(self、installmodule、runmodule、installerloc、installationloc、dependencyloc): self.installmodule=installmodule self.runmodule=runmodule self.installerloc=installerloc self
今天我将代码从
线程化
转移到多进程
。一切似乎都正常,直到我出现以下错误:
错误
component.py
类组件(对象):
def u u init u u;(self、installmodule、runmodule、installerloc、installationloc、dependencyloc):
self.installmodule=installmodule
self.runmodule=runmodule
self.installerloc=installerloc
self.installationloc=installationloc
self.dependencyloc=dependencyloc
self.config=icnf.Installconfiguration(installerloc+'/conf.conf')
#很多功能。。。
installconfig.py
class State(Enum):
BEGIN=0 #Look for units
UNIT=1 #Look for unit keypairs
KEYPAIR=3
class Phase(Enum):
NONE=0
DEPS=1
PKGS=2
class Installconfiguration(object):
def __init__(self, config):
dictionary = self.reader(config) #Fill a dictionary
#dictionary (key:Phase, value: (dictionary key: str, job))
self.deps = dictionary[Phase.DEPS]
self.pkgs = dictionary[Phase.PKGS]
job.py
class Job(object):
def __init__(self, directory=None, url=None):
self.directory = directory if directory else ''
self.url = url if url else ''
如您所见,我将一个组件作为参数传递给函数phase2(component、str、str、multiprocess.manager.Queue())
component
的构造函数的第二个和第三个参数是使用importlib
导入的模块
我试过的 我不熟悉python,但不熟悉编程。以下是我尝试过的:
- 因为错误本身没有指出问题的确切原因,所以我尝试删除arg以找出哪些不能被pickle:Remove
,并且一切正常,因此这似乎是出现问题的原因。但是,我需要将此对象传递给我的进程component
- 我在互联网上搜索了几个小时,但除了关于多重处理的基本教程和关于pickle如何工作的解释外,什么也没找到。我确实发现说它应该有用,但不是在窗户上或其他什么东西上。但是,它在Unix(我使用的)上不起作用
组件
类的确切问题是什么,但importlib模块作为成员是唯一非常规的东西。这就是为什么我认为问题出现在这里
问题: 你知道为什么包含模块的类不适合“酸洗”吗?如何更好地了解
不能pickle
错误发生的原因和位置
更多代码
有关此功能的完整源代码,请访问
对我的问题
请留下评论,要求澄清/更多代码片段/???如果你想让我编辑这个问题
最后的请求
我希望解决方案只使用python标准库,最好使用python 3.3。另外,我的代码要求它在Unix系统上运行
提前谢谢
编辑 根据要求,这里有一个大大简化问题的最小示例:
main.py(可以作为python main.py foo执行)
#/usr/bin/env python
导入系统
导入导入库
导入多处理
类别类别类别(对象):
定义初始值(自身,模块):
自模=模
def foopass(自紧):
self.moduly.foo(stringy)
def barpass(自、细、编号):
自模钢筋(细钢筋)
print('第二个参数:'+str(numbery))
def工人(clazzy,编号):
clazzy.barpass(“哇”,数字)
def main():
clazzy=clazz(importlib.import_模块(sys.argv[1]))
clazzy.foopass('init')
args=[(clazzy,2,)]
将multiprocessing.Pool(processs=2)作为池:
pool.starmap(worker,args)
如果名称=“\uuuuu main\uuuuuuuu”:
main()
foo.py(需要位于上述呼叫建议的同一目录中):
#/usr/bin/env python
全局=0
def foo(stringy):
打印('foo'+stringy)
全球
全局=5
def条(严格):
打印('bar'+stringy)
打印(str(全球))
运行时会出现错误:TypeError:无法pickle模块对象
现在我们知道酸洗模块对象是不可能的。为了消除错误,让
clazz
不管多么方便,都不要将模块作为属性,而是让它使用“modpath
”,这是importlib
导入用户指定模块所需的字符串。看起来是这样的(foo.py与上面的完全相同):
#/usr/bin/env python
导入系统
导入导入库
导入多处理
类别类别类别(对象):
定义初始(自我,模式):
self.modpathy=modpathy
def foopass(自紧):
moduley=importlib.import\u模块(self.modpathy)
moduly.foo(stringy)
def barpass(自、细、编号):
moduley=importlib.import\u模块(self.modpathy)
模杆(细杆)
print('第二个参数:'+str(numbery))
def工作人员(clazzy,编号):
克拉齐·巴帕斯(“哇”,数字)
def main():
clazzy=clazz(sys.argv[1])
clazzy.foopass('init')
args=[(clazzy,2,)]
将multiprocessing.Pool(processs=2)作为池:
pool.starmap(worker,args)
如果名称=“\uuuuu main\uuuuuuuu”:
main()
如果您要求保证您的全局变量(如globaly
)保持状态,则需要传递一个可变对象(如列表、字典)来保存此数据,谢谢@davishering:
模块属性在Python中称为“全局变量”,但它们并不比任何其他数据更持久或更易访问。为什么不用字典呢
示例代码如下所示:
#/usr/bin/env python
导入系统
导入导入库
导入多处理
类别类别类别(对象):
定义初始(自我,模式):
self.modpathy=modpathy
self.dictionary={}
def foopass(自紧):
moduley=importlib.import\u模块(self.modpathy)
moduly.foo(stringy,self.dictionary)
def barpass(自、细、编号):
moduley=importlib.import\u模块(self.modpathy)
模条(stringy,self.dictionary)
print('第二个参数:'+str(numbery))
def工作人员(clazzy,编号):
克拉齐·巴帕斯(“哇”,数字)
def main():
clazzy=clazz(sys.argv[1])
clazzy.foopass('init')
args=[(clazzy,2,)]
将multiprocessing.Pool(processs=2)作为池:
class Job(object):
def __init__(self, directory=None, url=None):
self.directory = directory if directory else ''
self.url = url if url else ''