discord.py锁定所有频道的命令需要很长时间
discord.py Command for locking all channels takes a long time
我在我的 discord 机器人上有一个锁定频道的命令。锁定单个频道可以完美地工作,但是当我尝试锁定服务器中的所有频道时,这需要相当长的时间才能完成,具体取决于有多少频道。我不太确定是否有办法加快这个过程,但这是我的代码:
async def send_m(self, ctx, check: bool):
for c in ctx.guild.text_channels:
if c.overwrites_for(ctx.guild.default_role).send_messages != check:
await c.set_permissions(ctx.guild.default_role, send_messages = check)
#lock
@commands.check_any(commands.is_owner(), commands.has_permissions(manage_channels = True), commands.guild_only())
@_channel.command(name="lock",
brief="Locks channel(s).",
help="Lock current/all channel(s)"
)
async def _lock(self, ctx, channel=None):
overwrite = ctx.channel.overwrites_for(ctx.guild.default_role)
try:
if channel == None and overwrite.send_messages != False:
await ctx.channel.set_permissions(ctx.guild.default_role, send_messages = False)
await ctx.send("Locked.")
if channel == None and overwrite.send_messages == False:
await ctx.send("This channel is already locked.")
if channel == "all":
await ctx.send(f"This will **lock** *all* channels. Type `{confirm}` to confirm.")
def check(m):
return m.channel.id == ctx.channel.id and m.author.id == ctx.author.id
try:
msg = await self.bot.wait_for("message", timeout=30, check=check)
except asyncio.TimeoutError:
return await ctx.send("Time's up. Aborted.")
if msg.content.lower() != confirm:
return await ctx.send("Aborted.")
await ctx.send("Locking all channels...")
await self.send_m(ctx=ctx, check=False)
await ctx.send("Locked all channels ✅.")
except Exception as e:
raise e
如您所见,我尝试将其设为异步函数以查看是否有帮助,但没有用。难道我做错了什么?如有任何帮助,我们将不胜感激!
您编写了一个异步函数,但它并不是真正的运行异步。
async def send_m(self, ctx, check: bool):
for c in ctx.guild.text_channels:
if c.overwrites_for(ctx.guild.default_role).send_messages != check:
await c.set_permissions(ctx.guild.default_role, send_messages = check)
await
是阻塞操作。当您 运行 send_m
时,它会遍历通道并调用 c.set_permissions
,等待每个调用完成后再继续下一个调用。
相反,您应该在等待任何事情之前用事件循环安排所有 c.set_permissions
调用。一种常见的方法是为每个任务创建一个任务,然后收集它们。
tasks = []
for c in ctx.guild.text_channels:
if c.overwrites_for(ctx.guild.default_role).send_messages != check:
tasks.append(asyncio.create_task(c.set_permissions(ctx.guild.default_role, send_messages=check)))
await asyncio.gather(*tasks)
这会让您得到想要的结果。但是,在这里使用 create_task
没有直接好处,因为您的 for 循环是同步的,并且 none 的任务无论如何都可以启动。您可以执行与上述相同的操作,但删除 create_task
调用。
tasks = []
for c in ctx.guild.text_channels:
if c.overwrites_for(ctx.guild.default_role).send_messages != check:
tasks.append(c.set_permissions(ctx.guild.default_role, send_messages=check))
await asyncio.gather(*tasks)
我在我的 discord 机器人上有一个锁定频道的命令。锁定单个频道可以完美地工作,但是当我尝试锁定服务器中的所有频道时,这需要相当长的时间才能完成,具体取决于有多少频道。我不太确定是否有办法加快这个过程,但这是我的代码:
async def send_m(self, ctx, check: bool):
for c in ctx.guild.text_channels:
if c.overwrites_for(ctx.guild.default_role).send_messages != check:
await c.set_permissions(ctx.guild.default_role, send_messages = check)
#lock
@commands.check_any(commands.is_owner(), commands.has_permissions(manage_channels = True), commands.guild_only())
@_channel.command(name="lock",
brief="Locks channel(s).",
help="Lock current/all channel(s)"
)
async def _lock(self, ctx, channel=None):
overwrite = ctx.channel.overwrites_for(ctx.guild.default_role)
try:
if channel == None and overwrite.send_messages != False:
await ctx.channel.set_permissions(ctx.guild.default_role, send_messages = False)
await ctx.send("Locked.")
if channel == None and overwrite.send_messages == False:
await ctx.send("This channel is already locked.")
if channel == "all":
await ctx.send(f"This will **lock** *all* channels. Type `{confirm}` to confirm.")
def check(m):
return m.channel.id == ctx.channel.id and m.author.id == ctx.author.id
try:
msg = await self.bot.wait_for("message", timeout=30, check=check)
except asyncio.TimeoutError:
return await ctx.send("Time's up. Aborted.")
if msg.content.lower() != confirm:
return await ctx.send("Aborted.")
await ctx.send("Locking all channels...")
await self.send_m(ctx=ctx, check=False)
await ctx.send("Locked all channels ✅.")
except Exception as e:
raise e
如您所见,我尝试将其设为异步函数以查看是否有帮助,但没有用。难道我做错了什么?如有任何帮助,我们将不胜感激!
您编写了一个异步函数,但它并不是真正的运行异步。
async def send_m(self, ctx, check: bool):
for c in ctx.guild.text_channels:
if c.overwrites_for(ctx.guild.default_role).send_messages != check:
await c.set_permissions(ctx.guild.default_role, send_messages = check)
await
是阻塞操作。当您 运行 send_m
时,它会遍历通道并调用 c.set_permissions
,等待每个调用完成后再继续下一个调用。
相反,您应该在等待任何事情之前用事件循环安排所有 c.set_permissions
调用。一种常见的方法是为每个任务创建一个任务,然后收集它们。
tasks = []
for c in ctx.guild.text_channels:
if c.overwrites_for(ctx.guild.default_role).send_messages != check:
tasks.append(asyncio.create_task(c.set_permissions(ctx.guild.default_role, send_messages=check)))
await asyncio.gather(*tasks)
这会让您得到想要的结果。但是,在这里使用 create_task
没有直接好处,因为您的 for 循环是同步的,并且 none 的任务无论如何都可以启动。您可以执行与上述相同的操作,但删除 create_task
调用。
tasks = []
for c in ctx.guild.text_channels:
if c.overwrites_for(ctx.guild.default_role).send_messages != check:
tasks.append(c.set_permissions(ctx.guild.default_role, send_messages=check))
await asyncio.gather(*tasks)