gpt4 book ai didi

python - 需要等待同步函数中的函数

转载 作者:行者123 更新时间:2023-12-03 17:10:43 25 4
gpt4 key购买 nike

我已经尝试解决这个问题 2 天了,在 StackOverflow 中阅读了 50 道问题以及许多关于 Python 的文档。我不知道还能尝试什么。
我的代码

import discord
import re
from datetime import datetime
import mysql.connector
from discord.ext import commands, tasks
from discord.utils import get
import atexit
from pynput import keyboard
import asyncio
from asgiref.sync import async_to_sync, sync_to_async

# The currently active modifiers
current = set()

# The key combination to check
COMBINATIONS_MUTE = [
{keyboard.Key.shift, keyboard.KeyCode(char='a')},
{keyboard.Key.shift, keyboard.KeyCode(char='A')}
]


COMBINATIONS_UNMUTE = [
{keyboard.Key.shift, keyboard.KeyCode(char='b')},
{keyboard.Key.shift, keyboard.KeyCode(char='B')}
]



GUILD_ID=guild_id
CHANNELS = ""
GUILD = ""
VOICE_CHANNEL = ""

client = commands.Bot(command_prefix = ".")

def get_channel(name):
global CHANNELS
for channel in CHANNELS:
if (channel.name == name) and (channel.type.name == "voice"):
return channel
return False

def get_voice_channels():
global CHANNELS
channels = []
for channel in CHANNELS:
if (channel.type.name == "voice"):
channels.append(channel)
return channels

async def mute_all():
global VOICE_CHANNELS
print("mute all")
for channel in VOICE_CHANNELS:
for member in channel.members:
await member.edit(mute=True)

async def unmute_all():
global VOICE_CHANNELS
print("unmute all")
for channel in VOICE_CHANNELS:
for member in channel.members:
await member.edit(mute=False)


def on_press(key):
if any([key in COMBO for COMBO in COMBINATIONS_MUTE]) and not key in current:
current.add(key)
if any(all(k in current for k in COMBO) for COMBO in COMBINATIONS_MUTE):
asyncio.run(mute_all())
elif any([key in COMBO for COMBO in COMBINATIONS_UNMUTE]):
current.add(key)
if any(all(k in current for k in COMBO) for COMBO in COMBINATIONS_UNMUTE):
asyncio.run(unmute_all())

def on_release(key):
if any([key in COMBO for COMBO in COMBINATIONS_MUTE]):
current.remove(key)
elif any([key in COMBO for COMBO in COMBINATIONS_UNMUTE]):
current.remove(key)


@client.event
async def on_ready():
global GUILD
global CHANNELS
global VOICE_CHANNELS
global GUILD_ID

GUILD = client.get_guild(GUILD_ID)

CHANNELS = GUILD.channels

VOICE_CHANNELS = get_voice_channels()
print("bot ready")
loop = asyncio.get_event_loop()
with keyboard.Listener(on_press=on_press, on_release=on_release) as listener:
listener.join()

client.run('token')
基本上它应该做的是:
  • 当我按下 Shift+A 时,将每个语音 channel 中的所有人静音。
  • 当我按 Shitf+B 时,取消每个语音 channel 中的每个人的静音。

  • 问题是我需要等待 member.edit()但我不能,因为我不能等待 mute_all()也不是 unmute_all()因为 on_press(key)不是异步的,我不能让它异步,因为 keyboard_listener 不允许我。
    我试过的(没有工作)
  • 使用 asyncio.run()member.edit() .
  • 使用 asyncio.run()mute_all() .
  • 制作 on_press(key)异步。
  • 使用 async_to_sync()member.edit() .
  • 使用 async_to_sync()mute_all() .

  • 我不知道还能尝试什么。

    最佳答案

    keyboard.Listener 不是异步的,所以它会阻塞 on_ready 中的事件循环,您需要在执行程序中初始化监听器,在这种情况下我们可以使用默认的。
    这是我为让这点工作而改变的所有内容:

    def keyboard_listener():
    with keyboard.Listener(on_press=on_press, on_release=on_release) as listener:
    listener.join()

    @client.event
    async def on_ready():
    global GUILD
    global CHANNELS
    global VOICE_CHANNELS
    global GUILD_ID

    GUILD = client.get_guild(GUILD_ID)

    CHANNELS = GUILD.channels

    VOICE_CHANNELS = get_voice_channels()
    print("bot ready")

    loop.run_in_executor(None, keyboard_listener)


    loop = asyncio.get_event_loop()
    然后我替换了你所有的 asyncio.runloop.create_task如果我的说明不清楚,请随时提出问题,我有一个正常运行的版本。
    从异步到同步再到异步是非常糟糕的,但嘿它有效,所以我猜它并不愚蠢
    我也换了你的 mute_allunmute_all稍微,因为您当前的实现只会影响机器人最初连接时在 channel 中的语音用户。这是我的更改示例:
    async def mute_all():
    print("mute all")
    for channel in client.get_guild(GUILD_ID).channels:
    if not channel.type.name == "voice":
    continue
    for member in channel.members:
    await member.edit(mute=True)

    关于python - 需要等待同步函数中的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63876614/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com