Python namedtuple作为参数来应用\u async(..)callb

2024-10-01 04:44:11 发布

您现在位置:Python中文网/ 问答频道 /正文

我在写一个简短的程序,我想异步调用一个函数,这样它就不会阻塞调用方。为此,我使用python的multiprocessing模块中的Pool。在

在异步调用的函数中,我想返回一个namedtuple,以适应程序其余部分的逻辑,但我发现namedtuple似乎不是从派生进程传递到回调的受支持类型(可能是因为它不能被pickle)。这是对这个问题的最低限度的解释。在

from multiprocessing import Pool
from collections import namedtuple

logEntry = namedtuple("LogEntry", ['logLev', 'msg'])

def doSomething(x):
    # Do actual work here
    logCode = 1
    statusStr = "Message Here"
    return logEntry(logLev=logCode, msg=statusStr)

def callbackFunc(result):
    print(result.logLev)
    print(result.msg)

def userAsyncCall():
    pool = Pool()
    pool.apply_async(doSomething, [1,2], callback=callbackFunc)

if __name__ == "__main__":
    userAsyncCall() # Nothing is printed

    # If this is uncommented, the logLev and status are printed as expected:
    # y = logEntry(logLev=2, msg="Hello World")
    # callbackFunc(y)

有人知道是否有方法将namedtuple返回值从异步进程传递到回调?对于我正在做的事情,有没有更好/更像Python的方法?在


Tags: 函数fromimport程序进程defmsgresult
2条回答

未打印任何内容的原因是apply_async静默失败。顺便说一句,我认为这是一种让人困惑的坏行为。您可以传递error_callback来处理错误。在

def errorCallback(exception):
    print(exception)

def userAsyncCall():
    pool = Pool()
    pool.apply_async(doSomething, [1], callback=callbackFunc,  error_callback=errorCallback)
    # You passed wrong arguments. doSomething() takes 1 positional argument.
    # I replace [1,2] with [1].

if __name__ == "__main__":
    userAsyncCall()
    import time
    time.sleep(3) # You need this, otherwise you will never see the output.

当你来的时候

^{pr2}$

皮克林杰罗!你说得对,namedtuple不能从派生进程传递到回调。

也许这不是一种更容易接受的方式,但您可以发送dict作为结果,而不是{}。

正如daghøidahl所纠正的,namedtuple可以被传递。下面这行行行得通。在

LogEntry = namedtuple("LogEntry", ['logLev', 'msg'])

问题是namedtuple()的返回值及其typename参数的大小写是不同的。也就是说,命名元组的类定义和您给它的变量名不匹配。你需要两者匹配:

LogEntry = namedtuple("LogEntry", ['logLev', 'msg'])

并相应地更新doSomething()中的return语句。在

完整代码:

^{pr2}$

(要查看类定义,请将verbose=True添加到namedtuple()。)

相关问题 更多 >