当前位置: 首页 > 面试题库 >

Python多处理池映射:AttributeError:无法腌制本地对象

欧阳昊阳
2023-03-14
问题内容

我在一个类中有一个方法,该方法需要循环执行大量工作,我想将工作分散到我的所有核心上。

我编写了以下代码,如果我使用normal map,则可以使用,但是pool.map返回错误。

import multiprocessing
pool = multiprocessing.Pool(multiprocessing.cpu_count() - 1)

class OtherClass:
  def run(sentence, graph):
    return False

class SomeClass:
  def __init__(self):
    self.sentences = [["Some string"]]
    self.graphs = ["string"]

  def some_method(self):
      other = OtherClass()

      def single(params):
          sentences, graph = params
          return [other.run(sentence, graph) for sentence in sentences]

      return list(pool.map(single, zip(self.sentences, self.graphs)))


SomeClass().some_method()

错误:

AttributeError:无法腌制本地对象“ SomeClass.some_method..single”

为什么不能泡菜single?我什至尝试移动single到全局模块范围(不在类内部-使其独立于上下文):

import multiprocessing
pool = multiprocessing.Pool(multiprocessing.cpu_count() - 1)

class OtherClass:
  def run(sentence, graph):
    return False


def single(params):
    other = OtherClass()
    sentences, graph = params
    return [other.run(sentence, graph) for sentence in sentences]

class SomeClass:
  def __init__(self):
    self.sentences = [["Some string"]]
    self.graphs = ["string"]

  def some_method(self):
      return list(pool.map(single, zip(self.sentences, self.graphs)))


SomeClass().some_method()

我收到以下错误:

AttributeError:无法从’… / test.py’获取模块’ main ‘上的属性’single ‘


问题答案:

AttributeError:无法腌制本地对象“ SomeClass.some_method..single”

您可以通过将嵌套的目标函数single()移到顶层来自己解决此错误。

背景:

Pool需要对其发送到其工作进程(IPC)的所有内容进行腌制(序列化)。酸洗实际上仅保存函数的名称,而酸洗则需要按名称重新导入该函数。为此,必须在顶层定义函数,子级将不能导入嵌套函数,并且已经尝试将其腌制会引发异常。

错误2:

AttributeError:无法从“ … / test.py”获取模块“ main”上的属性“ single”

定义函数和类 之前
先启动池,这样子进程就不能继承任何代码。将您的池启动到最底部并用以下方法保护(为什么?)if __name__ == '__main__':

import multiprocessing

class OtherClass:
  def run(self, sentence, graph):
    return False


def single(params):
    other = OtherClass()
    sentences, graph = params
    return [other.run(sentence, graph) for sentence in sentences]

class SomeClass:
   def __init__(self):
       self.sentences = [["Some string"]]
       self.graphs = ["string"]

   def some_method(self):
      return list(pool.map(single, zip(self.sentences, self.graphs)))

if __name__ == '__main__':  # <- prevent RuntimeError for 'spawn'
    # and 'forkserver' start_methods
    with multiprocessing.Pool(multiprocessing.cpu_count() - 1) as pool:
        print(SomeClass().some_method())

附录

…我希望将工作分散到我的所有核心。

有关multiprocessing.Pool分块工作方式的潜在帮助背景:

Python多处理:了解块大小背后的逻辑



 类似资料:
  • 我甚至不能使用Python 2.7中运行的多重处理包(使用spyder作为窗口上的用户界面)进行并行处理的最简单的例子,我需要帮助解决这个问题。我已经运行了conda更新,所以所有的包都应该是最新的和兼容的。 即使多处理软件包文档(如下所示)中的第一个示例也不起作用,它会生成4个新进程,但控制台只是挂起。在过去的3天里,我已经尝试了我能找到的一切,但是没有一个不挂起就运行的代码能够将我25%以上的

  • 我有一个图像路径列表,我想在进程或线程之间划分,以便每个进程处理列表的某些部分。处理包括从磁盘加载图像,进行一些计算并返回结果。我正在使用Python 2.7 下面是我如何创建辅助进程 我所面临的问题是,当我在initializer函数中记录初始化时间时,我知道worker不是并行初始化的,而是每个worker都以5秒的间隔初始化,下面是供参考的日志 我尝试过使用将同时启动辅助线程 我知道Wind

  • 问题内容: 使用时出现此错误: 没有说明,仅堆栈跟踪到模块内的pool.py文件。 使用这种方式: 我怀疑可挑剔性可能存在问题(python需要将列表数据转换为字节流,或者将列表数据转换为字节流),但是我不确定这是否正确或是否要调试。 编辑:产生此错误的代码的新格式: 产生错误: 问题答案: 在Python 2.x和3.0、3.1和3.2中,对象 不是上下文管理器 。您不能在语句中使用它们。只有在

  • 问题内容: 我想使用multiprocessing.Pool,但是multiprocessing.Pool不能在超时后中止任务。我找到了解决方案,并对其进行了一些修改。 主要修改-使用 sys.exit(1) 退出工作进程。它杀死了工作进程并杀死了工作线程,但是我不确定这个解决方案是否很好。当进程因正在运行的作业而终止时,我会遇到哪些潜在的问题? 问题答案: 停止正在运行的作业没有隐含的风险,操作

  • 我在为一些遗留代码构建REST体系结构方面遇到了一个问题。Jackson ObjectMapper无法将我的自定义对象映射到旧对象,因为“枚举”实际上是带有静态最终字段的类。 我尝试实现自定义转换器/反序列化程序,但没有成功 在旧系统中,有如下枚举: 我将这些“枚举”的值作为字符串接收,我将其转换为旧的枚举值(自定义反序列化器),并在自定义类中设置它们(我需要它,因为我使用的是jackson注释,

  • 问题内容: 是否有用于工作线程的类,类似于多处理模块的类? 我喜欢例如并行化地图功能的简单方法 但是,我希望这样做而不会产生新流程的开销。 我知道。但是,在我的用例中,该函数将是绑定的函数,python包装器将在实际函数调用之前为其释放。 我必须编写自己的线程池吗? 问题答案: 我刚刚发现模块中实际上 有一个基于线程的Pool接口,但是它有些隐藏并且没有正确记录。 可以通过导入 它是使用包装Pyt