并行Python:将另一个模块中编写的函数传递给'submit

3 投票
1 回答
1259 浏览
提问于 2025-04-18 10:52

我正在使用Parallel Python模块(pp),想要把一个任务提交给一个工作者。但是,我想执行的函数在另一个模块里(是用Cython写的),我不知道怎么把这个函数名导入到新的工作者中。这里建议的方法在函数内部导入模块"walkerc",但这行不通,因为walk本身是在walkerc中定义的,文件名是"walkerc.so"。

import pp
from walkerc import walk
# Other stuff here
ser = pp.Server()
# Some more definitions
ser.submit(walk, (it, params))
ser.submit(walk, (1000, params), modules = ("walkerc",), globals = globals())

上面的两个语句都失败了,我得到了以下错误信息:

追踪(最近的调用在最后):

文件 "", 第 1 行, 在 ser.submit(walk, (1000, params), modules = ("walkerc",), globals = globals())

文件 "/usr/lib/python2.7/site-packages/pp.py", 第 458 行, 在 submit sfunc = self.__dumpsfunc((func, ) + depfuncs, modules)

文件 "/usr/lib/python2.7/site-packages/pp.py", 第 629 行, 在 __dumpsfunc sources = [self.__get_source(func) for func in funcs]

文件 "/usr/lib/python2.7/site-packages/pp.py", 第 696 行, 在 __get_source sourcelines = inspect.getsourcelines(func)[0]

文件 "/usr/lib/python2.7/inspect.py", 第 690 行, 在 getsourcelines lines, lnum = findsource(object)

文件 "/usr/lib/python2.7/inspect.py", 第 526 行, 在 findsource file = getfile(object)

文件 "/usr/lib/python2.7/inspect.py", 第 420 行, 在 getfile 'function, traceback, frame, or code object'.format(object))

类型错误: '<'内置函数 walk'>' 不是模块、类、方法、函数、追踪、帧或代码对象

函数'walk'在主程序中导入得很好,但提交给新工作者的过程出现了问题。

我该如何正确指定函数名'walk'?我不想在调用它的同一个文件中定义'walk',因为我在Cython中修改过它,想要获得更好的性能。有没有其他的办法?

1 个回答

2

试着把你的 walk 函数改个名字,比如叫 mywalk。因为错误信息提示,你的环境里似乎有一个内置的函数也叫 walk,所以 inspect 模块就搞混了。

在我的系统上,我可以顺利地使用我导入的 walk 函数,没冲突,也不需要其他操作,函数会根据给定的参数执行:

import pp
from walkerc import walk

pps = pp.Server()
pps.submit(walk, args=(1,))

但是如果我传入 dir,这个是肯定的内置函数:

pps.submit(dir)

我遇到的错误和你的一模一样:

Traceback (most recent call last):
  File "parallel.py", line 9, in 
    pps.submit(dir)
  ...
  File ".../lib/python2.7/inspect.py", line 420, in getfile
    'function, traceback, frame, or code object'.format(object))
TypeError:  is not a module, class, method, function, traceback, frame, or code object

在下面讨论后的更新:

所以这里的问题是,Python把来自 C扩展 的成员当作内置函数来处理。上面的代码在普通的Python模块中可以正常工作,但当我从C扩展导入并传递函数时,我能重现原问题的错误。

因此,我把C扩展的函数调用包裹在一个普通的Python函数里,这样就解决了问题。注意,现在 walk 函数的导入被移动到了这个包裹函数里,这样它可以在调用时构建自己的上下文。

import pp

def walk(n):
    import walkerc
    return walkerc.walk(n)

def print_callback(result):
    print('callback: ', result)

pps = pp.Server()
job = pps.submit(walk, args=(1,), callback=print_callback)

撰写回答