【发布时间】:2021-04-22 16:25:51
【问题描述】:
我正在尝试将multiprocessing 与python Pool 函数一起使用,使用functools.partial 将几个具有常量值的参数输入到pool.map 命令中(即第一个参数是唯一的变量)。
问题是当我运行代码时出现以下错误,我不知道为什么或如何解决它:
AttributeError: Can't pickle local object
'get_MAX_SNR_for_eventdata_file.<locals>.get_SNR_multiprocess'
我不知道为什么它不能腌制一个物体。这是代码(在顶级函数中):
def get_SNR_multiprocess(binning, event_data, energy_interval, tstart, tstop, trigger_time):
""" This function just changes the order of arguments to be able to use partial"""
SNR=get_max_SNR_est(event_data, energy_interval, binning, tstart, tstop, trigger_time)
return SNR
pool=multiprocessing.Pool(processes=4)
for i in range(len(energybands)-1):
energy_interval=[energybands[i],energybands[i+1]]
partial_func=partial(get_SNR_multiprocess, event_data=event_data,
energy_interval=energy_interval, tstart=tstart, tstop=tstop,
trigger_time=trigger_time)
SNRlist=pool.map(partial_func,timescales)
pool.close()
根据What can be pickled?,我得到一个提示,这个问题可能与只有在模块顶层定义的函数才能被腌制这一事实有关。但是,我无法准确找出我的代码中的问题,或者如何解决它。
代码中的函数get_max_SNR_est是在同一个脚本中定义的函数,并返回一个值。此函数依赖于同一脚本的其他函数(依赖于另一个函数,依此类推...)。
仅供参考,代码无需使用 for 循环进行多处理即可工作,例如:
SNRlist=[]
for i in range(len(energybands)-1):
energy_interval=[energybands[i],energybands[i+1]]
for binning in timescales:
SNR=get_max_SNR_est(event_data, energy_interval, binning, tstart, tstop,
trigger_time)
SNRlist.append(SNR)
编辑:我忘了说明我在这里展示的代码已经在一个函数中了。根据@martineau 的评论,我将get_SNR_multiprocessing 函数从上述函数中取出,解决了酸洗问题(见答案)。
【问题讨论】:
-
问题是因为内部
partial()创建了一个partialobject,这显然不会发生在模块的顶层。错误消息显示get_SNR_multiprocess而不是partial_func的原因是因为这是partial赋予该对象的名称(即它“包装”了原始函数)。我不确定如何解决可变数量的partial对象的问题。 -
@martineau 你的评论帮助我解决了一个问题,通过将
get_SNR_multiprocess从主要功能中取出(我之前没有提到,但现在它已添加到帖子中)。现在,又出现了一个问题 -
我认为应该删除这个问题并提出一个新问题来解释你的新问题——因为酸洗问题已经解决了(不客气)。
-
完成。我没有在其他地方发布其他问题,因为我找到了解决方案。感谢您的反馈
标签: python multithreading pickle python-multiprocessing