Python - 如何使用池映射传递多个参数 [重复]

Posted

技术标签:

【中文标题】Python - 如何使用池映射传递多个参数 [重复]【英文标题】:Python - How can I pass multiple arguments using Pool map [duplicate] 【发布时间】:2017-02-07 02:45:42 【问题描述】:

这是我的代码片段:

data = [currentAccount.login,currentAccount.password,campaign.titlesFile,campaign.licLocFile,campaign.subCity,campaign.bodiesMainFile,campaign.bodiesKeywordsFile,campaign.bodiesIntroFile]
results = multiprocessing.Pool(5).map(partial(self.postAd,data),range(3))
...
def postAd (self,login,password,titlesFile,licLocFile,subCity,bodiesMainFile,bodiesKeywordsFile,bodiesIntroFile):
...

(让您知道发生了什么:currentAccount 和campaign 是类,它们是这些类中的变量。使用self b/c 这一切都在一个类中运行。我正在尝试运行self.postAd 3x 传递它是我在数据中的所有变量)

当我运行它时,它显示“postAd() 缺少 6 个必需的位置参数:'titlesFile'、'licLocFile'、'subCity'、'bodiesMainFile'、'bodiesKeywordsFile' 和 'bodiesIntroFile'”

我做错了什么?为什么它只接受 2 个变量?

如果我不能使用 Pool map,我应该怎么做?

我也试过了,但没有成功:

results = multiprocessing.Pool(5).map(lambda args: self.postAd(currentAccount.login,currentAccount.password,campaign.titlesFile,campaign.licLocFile,campaign.subCity,campaign.bodiesMainFile,campaign.bodiesKeywordsFile,campaign.bodiesIntroFile), range(3))

Error: Can't pickle <function NewPostService.processNewAds.<locals>.<lambda> at 0x0000000002F3CBF8>: attribute lookup <lambda> on functions failed

【问题讨论】:

我也试过这个没有成功: results = multiprocessing.Pool(5).map(lambda args: self.postAd(currentAccount.login,currentAccount.password,campaign.titlesFile,campaign.licLocFile, campaign.subCity,campaign.bodiesMainFile,campaign.bodiesKeywordsFile,campaign.bodiesIntroFile), range(3)) 错误:无法在 0x0000000002F3CBF8> 处腌制 .:属性查找 函数失败 您真的希望所有三个调用都完全使用相同的参数吗?我不确定它是否适用于map,因为它总是希望从它循环的序列中提供一个额外的参数(在这种情况下为range)。您可以通过编写一个忽略其最后一个参数的额外函数(并使用partial(self.postadd, *data))使其工作,但使用您自己的循环创建Processes 可能更容易。 是的,我希望它使用相同的参数。我希望相同的过程同时发生 3 次,这就是原因。我将如何做到这一点“但使用您自己的循环创建流程可能更容易。”如果你好心,你能给我一个基于我的代码的例子吗 【参考方案1】:

您的第一次尝试是滥用partialdata 是一个参数:它是一个列表并不会自动解包其内容。 partial 只接受可变参数,因此您应该“正常”传递这些参数,要么

partial(self.postAd, currentAccount.login,currentAccount.password, ...

partial(self.postAd, *data)

它说postAd 收到两个参数而不是一个 (data) 的原因是它还隐式收到了 self 参数。

您的第二次尝试是正确的想法并且非常接近,但碰巧in older versions of python pickle (which is essential for multiprocessing) can't handle lambdas。将 lambda 替换为使用 def 定义的命名函数:

def postNow(arg):  # Accepts an argument from map which it ignores
    self.postAd(currentAccount.login, ..., campaign.bodiesIntroFile)

旁注:

当它只是一个参数时,你的 lambda 参数被称为 args 有点奇怪。如果您的意图是使其灵活并接受可变参数,请使用lambda *args: ... 甚至lambda *args, **kwargs: ... 来接受关键字参数。名称并不重要,它们只是约定俗成的。重要的部分是***。请注意,partial 具有这样的签名,例如。

我以前从未在第二次尝试时遇到过这个问题。我是通过谷歌搜索错误消息了解到的。始终使用 Google 搜索。

【讨论】:

感谢亚历克斯的回复。我仍然是一个初学者 python 程序员,所以其中一些超出了我的想象。我尝试了 1. partial(self.postAd, *data) 和 2. multiprocessing.Pool(5).map(partial(self.postAd,currentAccount.login,currentAccount.password,campaign.titlesFile,campaign.licLocFile) 这两个选项,campaign.subCity,campaign.bodiesMainFile,campaign.bodiesKeywordsFile,campaign.bodiesIntroFile),range(3) ----------------- . 并得到了他们两个的这个错误:错误:postAd() 接受 9 个位置参数,但给出了 10 个。我不确定第 10 个参数在哪里,因为我只通过了 8 个。 @DanielRusu 它得到了 8 个普通参数,self,第 10 个是来自range(3) 的值,由map 传入。在这种情况下修改postAd 没有多大意义,所以实际上只是忘记尝试使用partial,它不是为此而设计的。

以上是关于Python - 如何使用池映射传递多个参数 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

ThreadLocal父子线程数据传递解决方案

如何在python中映射具有多个参数的函数

14.Vue路由参数传递以及重定向

VueRouter 参数传递与重定向

mybatis传递多个参数的问题

理解 python 中的 lambda 并使用它来传递多个参数