我正在使用python 3.6 django 1.11 windows10并尝试使用多处理发送电子邮件。
收件人连接到数据库(django模型),电子邮件内容表单是html(由django get_template),也使用get_connection发送多封电子邮件。我正在尝试的是使用多处理来加速发送速率。
我的代码在这里
from django.core.management.base import BaseCommand
from django.core.mail import get_connection, EmailMessage
from django.template.loader import get_template
from multiprocessing import Pool
from sending.models import Subscriber
class Command(BaseCommand):
def handle(self, *args, **options):
connection = get_connection()
recipients = [i.email for i in Subscriber.objects.all()]
num = Subscriber.objects.count()
subject = 'Multiprocessing trying 1'
body = get_template('Newsletter20171229.html').render()
from_email = 'info@modoodoc.com'
def send(i):
msg = EmailMessage(subject, body, from_email, [recipients[i]])
msg.content_subtype = 'html'
print("Sending email to: " + recipients[i] + " No: " + str(i))
connection.send_messages([msg])
print("Complete.")
pool = Pool(processes=2)
pool.map(send, range(0, num))
print("Mail have just sent. The program is going to end.")
connection.close()
我有这样的错误。
File "c:\python36-32\Lib\multiprocessing\connection.py", line 206, in send
self._send_bytes(_ForkingPickler.dumps(obj))
File "c:\python36-32\Lib\multiprocessing\reduction.py", line 51, in dumps
cls(buf, protocol).dump(obj)
AttributeError: Can't pickle local object 'Command.handle.<locals>.f'
如何解决这个问题?
谢谢。
答案 0 :(得分:0)
您必须从send
(以及handle
类)中取出本地函数Command
,并将放在模块的顶层,到unix_socket_directories
option。
对于subject
,body
,from_email
等封闭变量,您可以将它们捆绑在tuple
中并将tuple
作为单个传递send
的论点。或者更好的是,在msg
之外创建send
个对象,并将msg
列表传递给pool.map()
:
msg_list = [EmailMessage(subject, body, from_email, [recipients[i]])
for i in range(0, num)]
for msg in msg_list
msg.content_subtype = 'html'
pool = Pool(processes=2)
pool.map(send, msg_list)
其中模块级 send
函数的定义如下:
def send(msg):
print("Sending email to: {}".format(msg.recipients()[0]))
connection.send_messages([msg])
print("Complete.")