【问题标题】:Kick all command踢所有命令
【发布时间】:2019-10-04 01:24:57
【问题描述】:

我需要一个 kick all 命令以有趣的方式终止服务器

@bot.command(pass_context=True)
async def kick_all(ctx):
    while True:
        for server_member in ctx.message.server.members:
            try:
                channel = bot.get_channel('540612578401976330')
                await bot.kick(server_member)
                await bot.send_message(channel, "someone got kicked")
            except discord.Forbidden:
                pass

输出:

Ignoring exception in command kick_all
Traceback (most recent call last):
  File "C:\Users\adamk\PycharmProjects\bot\venv\lib\site-packages\discord\ext\commands\core.py", line 50, in wrapped
    ret = yield from coro(*args, **kwargs)
  File "C:/Users/adamk/PycharmProjects/bot/Server_KillSwitch.py", line 18, in kick_all
    for server_member in ctx.message.server.members:
RuntimeError: dictionary changed size during iteration

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Users\adamk\PycharmProjects\bot\venv\lib\site-packages\discord\ext\commands\bot.py", line 846, in process_commands
    yield from command.invoke(ctx)
  File "C:\Users\adamk\PycharmProjects\bot\venv\lib\site-packages\discord\ext\commands\core.py", line 374, in invoke
    yield from injected(*ctx.args, **ctx.kwargs)
  File "C:\Users\adamk\PycharmProjects\bot\venv\lib\site-packages\discord\ext\commands\core.py", line 54, in wrapped
    raise CommandInvokeError(e) from e
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: RuntimeError: dictionary changed size during iteration

【问题讨论】:

    标签: python python-3.x discord discord.py


    【解决方案1】:

    您正在更改列表,并引发错误。使用

    @bot.command(pass_context=True)
    async def kick_all(ctx):
        members = ctx.message.server.members.copy();
        while True:
            for server_member in members:
                try:
                    channel = bot.get_channel('540612578401976330')
                    await bot.kick(server_member)
                    await bot.send_message(channel, "someone got kicked")
                except discord.Forbidden:
                    pass
    

    【讨论】:

    • 你会得到同样的异常,因为members = ctx.message.server.members 不复制 ctx.message.server.members,所以你仍然会在从它删除项目的同时迭代同一个字典。这是您的代码的简化版本,也会出错:D = {str(i):i for i in range(10)}; not_a_copy=D; [D.popitem() for _ in not_a_copy]
    • @ForceBru 已修复
    【解决方案2】:

    问题是您正在从ctx.message.server.members 中删除项目同时对其进行迭代,这是不允许的,也没有多大意义:下一个元素要做什么您删除了当前元素之前的元素?还是下一个?还是现在的?

    您可以通过遍历字典的副本来快速解决此问题:

    for server_member in ctx.message.server.members.copy():
        ...  # your code here
    

    【讨论】:

      猜你喜欢
      • 2020-09-16
      • 2021-01-15
      • 2021-06-01
      • 2019-05-13
      • 2021-07-27
      • 2021-11-13
      • 2020-12-31
      • 2020-11-18
      • 2021-06-30
      相关资源
      最近更新 更多