检查 Discord 服务器中成员的循环问题

Issue with a loop which checks members in a Discord server

我是 Python 的新手,所以这让我很困惑。我正在尝试检查列表中的所有成员,对于每个成员,它检查它是否是人 A/person B 或两者都不是,然后根据它是否是那个人来做某件事。出于某种原因,当第一个检查的人与它检查的人相同时,它说以下所有人也是那个人。 该代码用于删除不和谐服务器中的所有成员,少数成员除外(用于在小游戏后重置)。

async def serverreset(ctx):
for member in ctx.message.guild.members:
    print(member)
    if member == "person1#1234" or "person2#2345":
        print(f"Unable to ban {member.display_name}")
    else:
        await member.ban(reason="Reset", delete_message_days=7)
        print(f"Banned {member.display_name}")

运行 程序的结果:

person1#1234
Unable to ban person1
person2#2345
Unable to ban person2
accountthatshouldbebanned#5678
Unable to ban accountthatshouldbebanned

成员对象的字符串表示(即当被打印或放入字符串时)是用户名 + 鉴别符。但是当您在语句中使用成员对象时,它不会将其转换为字符串。

您可以通过以下几种方式解决此问题:

if str(member) in ["person1#1234", "person2#2345"]:
    print(f"Unable to ban {member.display_name}")
else:
    # other code

这会将成员作为字符串进行检查。另一种方法是通过 ID(更 "failsafe",因为 ID 永远不会改变,但用户可以更改他们的名字和鉴别符)。

if member.id in [112233445566778899, 223344556677889900]:
    print(f"Unable to ban {member.display_name}")
else:
    # other code

另一件需要注意的事情是,当机器人编辑角色、尝试更改用户名或 kick/ban 某人并且该人比机器人(即服务器所有者)拥有更高的权限时,它会抛出 Forbidden 错误,因为它在层次结构中的级别不够高,无法执行该操作。

最后一件事是在您的 if 语句中,您正在检查 member == "person#1234" or "person2#2345",这在简单的英语中非常有意义。但是,当解释器评估语句时,它会单独执行它们:

  • if member == "person1#1234"
  • if "person2#2345"

由于第二部分,它将始终评估为 True,并且仅当对象为 None 时才为 False,但因为字符串不是None,它将是 True

希望说得通。


参考文献:

表达式member == "person1#1234" or "person2#2345" 实际上解析为 ( member == "person1#1234") or ("person2#2345),它将始终计算为 True

你需要使用 member == "person1#1234" or member == "person2#2345".

你也可以使用 member in ("person1#1234", "person2#2345")