python - 不和谐 python 机器人 : AttributeError: Can't pickle local object

标签 python class pickle attributeerror discord.py

您好,我正在尝试使用创建 worker 并检索不和谐消息以将它们放入队列的主类来多处理我的不和谐机器人。当我初始化我的 worker 时,我将我的不和谐客户端作为参数传递,这是错误。

AttributeError: Can't pickle local object 'WeakSet.__init__.<locals>._remove'

我的代码:

class Master:
    def __init__(self):
        # Vars init
        print('Starting Master...')
        self.client = discord.Client()
        self.manager = Manager()
        self.user_spam = self.manager.dict()
        self.user_mute_chat = self.manager.dict()
        self.forbidden_words_list = []
        self.spam_t = self.manager.Value('i', 0)
        self.user_t_spam_muted = self.manager.Value('i', 0)
        self.to_master = []
        self.request_queue = Queue()
        self.cpu = cpu_count()

        # Web socket handlers
        # self.client.event(self.on_member_update)
        self.client.event(self.on_ready)
        self.client.event(self.on_message)

        # Bot init
        self.forbidden_words_list = self.manager.list(get_file_content('res/forbidden_words.txt'))
        for line in get_file_content('res/settings.txt'):
            if 'spamtime=' in line:
                self.spam_t = int(line.replace('spamtime=', ''))
            if 'usertimemuted' in line:
                self.user_t_spam_muted = int(line.replace('usertimemuted=', ''))

        # Workers init
        print('Starting Workers...')
        for i in range(self.cpu):
            Worker(self.request_queue, self.client, self.user_spam, self.user_mute_chat, self.spam_t,
                   self.user_t_spam_muted, self.forbidden_words_list).start()

        # Discord init
        print('Connecting to discord...')
        self.client.run(TOKEN)

class Worker(Process):
    def __init__(self, queue, client, user_spam, user_mute_chat, spam_t, user_t_spam_muted, forbidden_words_list):
        super(Worker, self).__init__()
        # Vars init
        self.client = client
        self.message = ''
        self.message_id = discord.Message
        self.word_list = []
        self.username = discord.Member
        self.queue = queue
        self.user_spam = user_spam
        self.user_mute_chat = user_mute_chat
        self.spam_t = spam_t
        self.user_t_spam_muted = user_t_spam_muted
        self.forbidden_words_list = forbidden_words_list

    async def run(self):
        # do some initialization here

        # Work here
        for data in iter(self.queue.get, None):
            pass

完整追溯:

Traceback (most recent call last):
  File "C:/Users/PC/PycharmProjects/AIDiscord/AIDiscord.py", line 406, in <module>
    master = Master()
  File "C:/Users/PC/PycharmProjects/AIDiscord/AIDiscord.py", line 42, in __init__
    self.user_t_spam_muted, self.forbidden_words_list).start()
  File "C:\Users\PC\AppData\Local\Programs\Python\Python36-32\Lib\multiprocessing\process.py", line 105, in start
    self._popen = self._Popen(self)
  File "C:\Users\PC\AppData\Local\Programs\Python\Python36-32\Lib\multiprocessing\context.py", line 223, in _Popen
    return _default_context.get_context().Process._Popen(process_obj)
  File "C:\Users\PC\AppData\Local\Programs\Python\Python36-32\Lib\multiprocessing\context.py", line 322, in _Popen
    return Popen(process_obj)
  File "C:\Users\PC\AppData\Local\Programs\Python\Python36-32\Lib\multiprocessing\popen_spawn_win32.py", line 65, in __init__
    reduction.dump(process_obj, to_child)
  File "C:\Users\PC\AppData\Local\Programs\Python\Python36-32\Lib\multiprocessing\reduction.py", line 60, in dump
    ForkingPickler(file, protocol).dump(obj)
AttributeError: Can't pickle local object 'WeakSet.__init__.<locals>._remove'
Unclosed client session
client_session: <aiohttp.client.ClientSession object at 0x0EDDAED0>

我搜索了更多,它在我 start() 进程时追加,它不依赖于我传递的参数。

最佳答案

您需要在 multiprocessing.Process.run 中创建异步循环和相关项目的实例。而不是初始化。
我使用的模式是这样的:

import asyncio
import multiprocessing
import typing


class Process(multiprocessing.Process):

    def __init__(self,
                 group=None,
                 target=None,
                 name=None,
                 args=(),
                 kwargs=None):
        super().__init__(group, target, name, args, kwargs)
        self.loop: typing.Optional[asyncio.AbstractEventLoop] = None
        self.stopped: typing.Optional[asyncio.Event] = None

    def run(self):
        self.loop = asyncio.get_event_loop()
        self.stopped = asyncio.Event()
        self.loop.run_until_complete(self._run())
    
    async def _run(self):
        """My async stuff here"""

关于python - 不和谐 python 机器人 : AttributeError: Can't pickle local object,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50550905/

相关文章:

python - python 3中类 'bytes'的不同表示

java - 为什么Java中Integer类的2个对象不能相等

python - 如果我自己在 Python 中 pickle 一个字符串,解封它会很危险吗?

python - pathlib.Path 的子类对象在 pickle.load 后丢失自定义属性

python - 在 python 中 pickle 数据时出现 MemoryError

python - 将 python 颜色图修改为超出特定点的单个值

python - 我可以在程序中多次调用函数 'main' 吗?

c# - 我如何从方法返回 IEnumerable<T>

Python Pandas - 如何格式化和拆分列中的文本?

Android Python 获取gps状态