首页 > 解决方案 > 动态导入模块中的多处理

问题描述

我有两个班级AB. A应该动态导入B(所以我可以B在运行时更改)。我也想在B.

这是我的目录结构:

src\
  __init__.py
  a\
    __init__.py
    a.py
  b\
    __init__.py
    b.py

这是一个.py:

import os, importlib.util

if __name__ == '__main__':
  module_path = 'src\\b\\b.py'
  module_name = 'b'
  class_name = 'B'

  # dynamically importing the module
  spec = importlib.util.spec_from_file_location(module_name, module_path)
  module = importlib.util.module_from_spec(spec)
  spec.loader.exec_module(module)

  # dynamically instantiating the class
  b_class = getattr(module, class_name)
  b = b_class()

  # start multiprocessing
  b.run()

这是 b.py:

import multiprocessing as mp

class B():
  def f(self):
    print('success')

  def run(self):
    print('run')
    p = mp.Process(target=self.f)
    p.start()
    p.join()

if __name__ == '__main__':
  b = B()
  b.run()

运行 b.py 工作正常:

> python src\b\b.py
run
success

运行 a.py 会引发异常:

> python src\a\a.py
run
Traceback (most recent call last):
  File "src\a\a.py", line 18, in <module>
    b.run()
  File "src\b\b.py", line 10, in run
    p.start()
  File "C:\Program Files\Python38\lib\multiprocessing\process.py", line 121, in start
    self._popen = self._Popen(self)
  File "C:\Program Files\Python38\lib\multiprocessing\context.py", line 224, in _Popen
    return _default_context.get_context().Process._Popen(process_obj)
  File "C:\Program Files\Python38\lib\multiprocessing\context.py", line 327, in _Popen
    return Popen(process_obj)
  File "C:\Program Files\Python38\lib\multiprocessing\popen_spawn_win32.py", line 93, in __init__
    reduction.dump(process_obj, to_child)
  File "C:\Program Files\Python38\lib\multiprocessing\reduction.py", line 60, in dump
    ForkingPickler(file, protocol).dump(obj)
_pickle.PicklingError: Can't pickle <class 'b.B'>: import of module 'b' failed

C:\Users\micha\Projects\Python\PickleQuestion>Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "C:\Program Files\Python38\lib\multiprocessing\spawn.py", line 102, in spawn_main
    source_process = _winapi.OpenProcess(
OSError: [WinError 87] Falscher Parameter

为什么?是否有另一种导入 B 的方法,同时保持不对其进行硬编码的灵活性(from b import B)?我希望 b.py 在任何包中,甚至在 src 之外。

Python版本:3.8.6

标签: pythonpython-3.xmultiprocessingpython-importpickle

解决方案


推荐阅读