如何使用Discord的客户端和asyncio修复此错误?

长话短说,我是API和异步编程的新手。我正在尝试制作一个Discord机器人,该机器人将您的Steam平台状态发布到bot的状态显示中(至少现在是这样),但是在运行Discord_Bot.py时出现此错误。不知道它是什么意思,为什么,但是它令我感到担忧,因为该错误似乎是在Discord的一个文件中发现的(我没有写过)。

首先,我在运行Discord_Bot.py之后立即收到此错误:

 Ignoring exception in on_ready
Traceback (most recent call last):
  File "C:\Users\Mira\Anaconda3\lib\site-packages\discord\client.py",line 307,in _run_event
    yield from getattr(self,event)(*args,**kwargs)
TypeError: on_ready() missing 1 required positional argument: 'self'


  File "C:\Users\USER\Anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py",line 705,in runfile
    execfile(filename,namespace)

  File "C:\Users\USER\Anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py",line 102,in execfile
    exec(compile(f.read(),filename,'exec'),namespace)

  File "C:/Users/USER/Documents/GitHub/Discord_Steam_Interface/Discord_Bot.py",line 83,in <module>
    b.run_the_bot()

  File "C:/Users/USER/Documents/GitHub/Discord_Steam_Interface/Discord_Bot.py",line 75,in run_the_bot
    self.client.run(self.__BOT_TOKEN)

  File "C:\Users\USER\Anaconda3\lib\site-packages\discord\client.py",line 534,in run
    self.loop.close()

  File "C:\Users\USER\Anaconda3\lib\asyncio\selector_events.py",line 107,in close
    raise RuntimeError("Cannot close a running event loop")

RuntimeError: Cannot close a running event loop

然后我应用了nest_asyncio补丁,可以在这里找到它: https://github.com/erdewit/nest_asyncio

这似乎解决了问题,因为在运行脚本后,我不再立即收到“ RuntimeError:无法关闭运行事件循环”错误。但是,我现在注意到,如果让它运行约5分钟,它会重新出现。此外,脚本运行后立即继续出现以下错误。我不知所措,需要帮助吗?

Ignoring exception in on_ready
Traceback (most recent call last):
  File "C:\Users\USER\Anaconda3\lib\site-packages\discord\client.py",**kwargs)
TypeError: on_ready() missing 1 required positional argument: 'self'

这是Discord_Bot.py :(我的文件)

import time
import win32gui
import psutil
import subprocess
import discord
import asyncio
import get_steam_info
import nest_asyncio

# Applies a patch which allows asyncio's event loop to be nested. 
nest_asyncio.apply()

class Bot_handler():

    # Define the Client object for this session.
    client = discord.Client()

    def __init__(self,program_name,steam_id,api_key,bot_token):
        self.program_name = program_name
        self.process = self.program_name + '.exe'
        self.__program_running = self.get_program_running(self.process)
        self.__STEAM_ID = STEAM_ID
        self.__API_KEY = API_KEY
        self.__BOT_TOKEN = BOT_TOKEN

    def get_program_running(self,process_str):
        '''Determine whether the specified process_str is running.'''
        if process_str in (process.name() for process in psutil.process_iter()):
            self.__program_running = True
            print(self.program_name,"is currently running.")
        else:
            self.__program_running = False
            print(self.program_name,"is not currently running.")
        return self.__program_running

    @client.event
    async def on_ready(self):
        '''Called automatically when client is done preparing data from Discord.
        Schedules coroutine on_ready using Task client.loop.create_task.'''
        self.__client.loop.create_task(self.status_task())
        print('Logged in as')
        print(self.__client.user.name)
        print(self.__client.user.id)
        print('------')

    async def status_task(self):
        while True:
            if self.__program_running:
                self.__player_info = get_steam_info.get_player_info(self.__API_KEY,self.__STEAM_ID)
                self.__player_status = get_steam_info.get_player_status(self.__player_info)
                self.__ingame = get_steam_info.get_ingame_name(self.__player_info)

                if self.__ingame:
                    await self.__client.change_presence(status = discord.Status.online,game = discord.Game(name = str(self.__ingame)),afk=False)
                    await asyncio.sleep(3)
                else:
                    await self.__client.change_presence(status = discord.Status.dnd,game = discord.Game(name = 'nothing at the moment'))
                    await asyncio.sleep(3)
            else:
                self.get_active_window()

    def get_active_window(self):
        '''Return the title of the active window as a string.'''
        self.__active_window = win32gui.GetWindowText(win32gui.GetForegroundWindow())
        return self.__active_window    

    def run_the_bot(self):
        # activates the bot.
        self.client.run(self.__BOT_TOKEN)


PROGRAM_NAME = 'Steam'

# Real values are present in the code 
STEAM_ID = 'ZZZZZZZZZ'
API_KEY = 'XXXXXXXX'
BOT_TOKEN = 'YYYYYYYYYY'       
b = Bot_handler(PROGRAM_NAME,STEAM_ID,API_KEY,BOT_TOKEN)
b.run_the_bot()

get_steam_info.py(我的文件)

import requests

class Info_handler():
    '''Keep track of a player's information in real time.'''
    def __init__(self,steam_ID,API_key):

        self.__steam_ID = steam_ID
        self.__API_key = API_key        
        self.__API_url = 'https://api.steampowered.com/ISteamUser/GetPlayerSummaries/v2/?key=' \
        + self.__API_key +'&steamids=' + self.__steam_ID
        self.statuslist = {0: 'offline',1: 'online',3: 'dnd',4: 'idle',5: 'idle',6: 'online',7: 'online'}
        # call status

        # profile_url = 'https://steamcommunity.com/profiles/' + steam_ID

        self.__player_info = self.get_player_info()
        self.__player_status = self.get_player_status(self.__player_info)

    def get_player_info(self):
        '''Returns a dict containing Steam information for one player using the
        Steam API. Requires the desired player's user ID and a valid API key.'''
        self.response = requests.get(self.__API_url)

        if self.response.status_code != 200:
            raise Exception('Request unsuccessful; returned code ' + str(self.response.status_code) \
            + ': ' + str(requests.status_codes._codes[self.response.status_code][0]))
        else:
            print('Success! API responded to call.')
            self.__player_info = self.response.json()['response']['players'][0]
        return self.__player_info

    def get_player_status(self,player_info_dict):
        '''Returns the player's Steam status as a Discord status type.

        STEAM STATUS        | STEAM STATE | DISCORD STATUS
        'Offline'           |      0      | 'Offline'
        'Online'            |      1      | 'Online'
        'Busy'              |      2      | 'dnd'
        'Away'              |      3      | 'Idle'
        'snooze'            |      4      | 'Idle'
        'Looking to trade'  |      5      | 'Online'
        'Looking to play'   |      6      | 'Online'
        '''
        self.__steam_state = player_info_dict['personastate']

        self.__player_status = self.statuslist[self.__steam_state]
        return self.__player_status

# Is it better to use 'self.__steam_state' since when this variable will never 
# called outside the function? Or shall I use simply 'steam_state?'

    def get_ingame_name(self,player_info_dict):
        '''Returns the name of the Steam game player is playing. 
        If player is logged into Steam,but not currently playing anything,return False.'''
        self.__player_name = player_info_dict['personaname']
        try:
            self.__game = player_info_dict['gameextrainfo']
            print('Player ',self.__player_name,' is playing ',self.__game,'.',sep='')
            return self.__game
        except KeyError:  
            print('Player','is not currently in a game.')
            return False

    def get_player_name(self):
        return self.__player_name

steam_ID = 'ZZZZZZZZZ'
API_key = 'XXXXXXXX'

instance = Info_handler(steam_ID,API_key)
info = instance.get_player_info()
print(info)
status = instance.get_player_status(info)
print(status)
game = instance.get_ingame_name(info)
print(game)
wangyi19890218 回答:如何使用Discord的客户端和asyncio修复此错误?

暂时没有好的解决方案,如果你有好的解决方案,请发邮件至:iooj@foxmail.com
本文链接:https://www.f2er.com/3148170.html

大家都在问