英文:
How can I resolve the error 'str' object has no attribute 'is_paused' in discord.py?
问题
以下是您要翻译的内容:
[2023-02-19 05:14:12] [ERROR] discord.ext.commands.bot: Ignoring exception in command play
Traceback (most recent call last):
File "C:\Users\toto\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\ext\commands\core.py", line 229, in wrapped
ret = await coro(*args, **kwargs)
File "C:\Users\toto\PycharmProjects\pythonProject\music_bot-main\main.py", line 101, in play
elif self.is_paused:
AttributeError: 'str' object has no attribute 'is_paused'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Users\toto\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\ext\commands\bot.py", line 1349, in invoke
await ctx.command.invoke(ctx)
File "C:\Users\toto\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\ext\commands\core.py", line 1023, in invoke
await injected(*ctx.args, **ctx.kwargs) # type: ignore
File "C:\Users\toto\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\ext\commands\core.py", line 238, in wrapped
raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: 'str' object has no attribute 'is_paused'
import discord
from discord.ext import commands
import os
import asyncio
import all of the cogs
from help_cog import help_cog
from music_cog import music_cog
intents = discord.Intents.all()
client = commands.Bot(command_prefix='.', intents=intents)
@client.event
async def on_ready():
print(f'Logged in as {client.user} (ID: {client.user.id})')
print('------')
remove the default help command so that we can write out own
client.remove_command('help')
register the class with the bot
bot.add_cog(help_cog(bot))
client.add_cog(music_cog(client))
code du bot
class music_cog(commands.Cog):
def init(self, bot):
self.bot = bot
# all the music related stuff
self.is_playing = False
self.is_paused = False
# 2d array containing [song, channel]
self.music_queue = []
self.YDL_OPTIONS = {'format': 'bestaudio', 'noplaylist': 'True'}
self.FFMPEG_OPTIONS = {'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5',
'options': '-vn'}
self.vc = None
# searching the item on youtube
def search_yt(self, item):
with YoutubeDL(self.YDL_OPTIONS) as ydl:
try:
info = ydl.extract_info("ytsearch:%s" % item, download=False)['entries'][0]
except Exception:
return False
return {'source': info['formats'][0]['url'], 'title': info['title']}
def play_next(self):
if len(self.music_queue) > 0:
self.is_playing = True
# get the first url
m_url = self.music_queue[0][0]['source']
# remove the first element as you are currently playing it
self.music_queue.pop(0)
self.vc.play(discord.FFmpegPCMAudio(m_url, **self.FFMPEG_OPTIONS), after=lambda e: self.play_next())
else:
self.is_playing = False
# infinite loop checking
async def play_music(self, ctx):
if len(self.music_queue) > 0:
self.is_playing = True
m_url = self.music_queue[0][0]['source']
# try to connect to voice channel if you are not already connected
if self.vc == None or not self.vc.is_connected():
self.vc = await self.music_queue[0][1].connect()
# in case we fail to connect
if self.vc == None:
await ctx.send("Could not connect to the voice channel")
return
else:
await self.vc.move_to(self.music_queue[0][1])
# remove the first element as you are currently playing it
self.music_queue.pop(0)
self.vc.play(discord.FFmpegPCMAudio(m_url, **self.FFMPEG_OPTIONS), after=lambda e: self.play_next())
else:
self.is_playing = False
@client.command(name="play", aliases=["p", "playing"], help="Plays a selected song from youtube")
async def play(ctx, self, *args):
query = " ".join(args)
voice_channel = ctx.author.voice.channel
if voice_channel is None:
# you need to be connected so that the bot knows where to go
await ctx.send("Connect to a voice channel!")
elif self.is_paused:
self.vc.resume()
else:
song = self.search_yt(query)
if type(song) == type(True):
await ctx.send(
"Could not download the song. Incorrect format try another keyword. This could be due to playlist or a livestream format.")
else:
await ctx.send("Song added to the queue")
self.music_queue.append([song, voice_channel])
if self.is_playing == False:
await self.play_music(ctx)
@client.command(name="pause", help="Pauses the current song being played")
async def pause(self, ctx, *args):
if self.is_playing:
self.is_playing = False
self.is_paused = True
self.vc.pause()
elif self.is_paused:
self.is_paused = False
self.is_playing = True
self.vc.resume()
@client.command(name="resume", aliases=["r"], help="Resumes playing with the discord bot")
async def resume(self, ctx, *args):
if self.is_paused:
self.is_paused = False
self.is_playing = True
self.vc.resume()
@client.command(name="skip", aliases=["s"], help="Skips the current song being played")
async def skip(self, ctx):
if self.vc != None and self.vc:
self.vc.stop()
# try to play next in the queue if it exists
await self.play_music(ctx)
@client.command(name="queue", aliases=["q"], help="Displays the current songs in queue")
async def queue(self, ctx):
retval = ""
for i in range(0, len(self.music_queue)):
# display a max of 5 songs in the current queue
if (i > 4): break
retval += self.music_queue[i][0]['title'] + "\n"
if retval != "":
await ctx.send(retval)
else:
英文:
> [2023-02-19 05:14:12] [ERROR ] discord.ext.commands.bot: Ignoring exception in command play
Traceback (most recent call last):
File "C:\Users\toto\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\ext\commands\core.py", line 229, in wrapped
ret = await coro(*args, **kwargs)
File "C:\Users\toto\PycharmProjects\pythonProject\music_bot-main\main.py", line 101, in play
elif self.is_paused:
AttributeError: 'str' object has no attribute 'is_paused'
> The above exception was the direct cause of the following exception:
>Traceback (most recent call last):
File "C:\Users\toto\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\ext\commands\bot.py", line 1349, in invoke
await ctx.command.invoke(ctx)
File "C:\Users\toto\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\ext\commands\core.py", line 1023, in invoke
await injected(*ctx.args, **ctx.kwargs) # type: ignore
File "C:\Users\toto\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\ext\commands\core.py", line 238, in wrapped
raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: 'str' object has no attribute 'is_paused'
import discord
from discord.ext import commands
import os
import asyncio
# import all of the cogs
# from help_cog import help_cog
# from music_cog import music_cog
intents = discord.Intents.all()
client = commands.Bot(command_prefix='.', intents=intents)
@client.event
async def on_ready():
print(f'Logged in as {client.user} (ID: {client.user.id})')
print('------')
# remove the default help command so that we can write out own
client.remove_command('help')
# register the class with the bot
# bot.add_cog(help_cog(bot))
# client.add_cog(music_cog(client))
# code du bot
class music_cog(commands.Cog):
def __init__(self, bot):
self.bot = bot
# all the music related stuff
self.is_playing = False
self.is_paused = False
# 2d array containing [song, channel]
self.music_queue = []
self.YDL_OPTIONS = {'format': 'bestaudio', 'noplaylist': 'True'}
self.FFMPEG_OPTIONS = {'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5',
'options': '-vn'}
self.vc = None
# searching the item on youtube
def search_yt(self, item):
with YoutubeDL(self.YDL_OPTIONS) as ydl:
try:
info = ydl.extract_info("ytsearch:%s" % item, download=False)['entries'][0]
except Exception:
return False
return {'source': info['formats'][0]['url'], 'title': info['title']}
def play_next(self):
if len(self.music_queue) > 0:
self.is_playing = True
# get the first url
m_url = self.music_queue[0][0]['source']
# remove the first element as you are currently playing it
self.music_queue.pop(0)
self.vc.play(discord.FFmpegPCMAudio(m_url, **self.FFMPEG_OPTIONS), after=lambda e: self.play_next())
else:
self.is_playing = False
# infinite loop checking
async def play_music(self, ctx):
if len(self.music_queue) > 0:
self.is_playing = True
m_url = self.music_queue[0][0]['source']
# try to connect to voice channel if you are not already connected
if self.vc == None or not self.vc.is_connected():
self.vc = await self.music_queue[0][1].connect()
# in case we fail to connect
if self.vc == None:
await ctx.send("Could not connect to the voice channel")
return
else:
await self.vc.move_to(self.music_queue[0][1])
# remove the first element as you are currently playing it
self.music_queue.pop(0)
self.vc.play(discord.FFmpegPCMAudio(m_url, **self.FFMPEG_OPTIONS), after=lambda e: self.play_next())
else:
self.is_playing = False
@client.command(name="play", aliases=["p", "playing"], help="Plays a selected song from youtube")
async def play(ctx, self, *args):
query = " ".join(args)
voice_channel = ctx.author.voice.channel
if voice_channel is None:
# you need to be connected so that the bot knows where to go
await ctx.send("Connect to a voice channel!")
elif self.is_paused:
self.vc.resume()
else:
song = self.search_yt(query)
if type(song) == type(True):
await ctx.send(
"Could not download the song. Incorrect format try another keyword. This could be due to playlist or a livestream format.")
else:
await ctx.send("Song added to the queue")
self.music_queue.append([song, voice_channel])
if self.is_playing == False:
await self.play_music(ctx)
@client.command(name="pause", help="Pauses the current song being played")
async def pause(self, ctx, *args):
if self.is_playing:
self.is_playing = False
self.is_paused = True
self.vc.pause()
elif self.is_paused:
self.is_paused = False
self.is_playing = True
self.vc.resume()
@client.command(name="resume", aliases=["r"], help="Resumes playing with the discord bot")
async def resume(self, ctx, *args):
if self.is_paused:
self.is_paused = False
self.is_playing = True
self.vc.resume()
@client.command(name="skip", aliases=["s"], help="Skips the current song being played")
async def skip(self, ctx):
if self.vc != None and self.vc:
self.vc.stop()
# try to play next in the queue if it exists
await self.play_music(ctx)
@client.command(name="queue", aliases=["q"], help="Displays the current songs in queue")
async def queue(self, ctx):
retval = ""
for i in range(0, len(self.music_queue)):
# display a max of 5 songs in the current queue
if (i > 4): break
retval += self.music_queue[i][0]['title'] + "\n"
if retval != "":
await ctx.send(retval)
else:
await ctx.send("No music in queue")
@client.command(name="clear", aliases=["c", "bin"], help="Stops the music and clears the queue")
async def clear(self, ctx):
if self.vc != None and self.is_playing:
self.vc.stop()
self.music_queue = []
await ctx.send("Music queue cleared")
@client.command(name="leave", aliases=["disconnect", "l", "d"], help="Kick the bot from VC")
async def dc(self, ctx):
self.is_playing = False
self.is_paused = False
await self.vc.disconnect()
@client.command()
async def bonjour(ctx):
await ctx.send("Bonjour")
# start the bot with our token
client.run(os.getenv("TOKEN"))
答案1
得分: 1
你在很多非类方法中都加入了self
参数。所以self
最终变成了你的context
对象,而ctx
是命令参数。只需从那些不需要self
的方法中移除self
。也就是说,那些不属于类的每个方法。
async def play(ctx, *args):
...
async def pause(ctx, *args):
...
async def resume(ctx, *args):
...
async def skip(ctx):
...
async def queue(ctx):
...
async def clear(ctx):
...
async def dc(ctx):
...
以上是需要更改的部分。
英文:
You've given lots of non-class methods the self
parameter. So self
ends up being your context
object and ctx
the command argument. Just remove self
from the methods that don't need it. ie, every method that doesn't belong to a class.
async def play(ctx, *args):
...
async def pause(ctx, *args):
...
async def resume(ctx, *args):
...
async def skip(ctx):
...
async def queue(ctx):
...
async def clear(ctx):
...
async def dc(ctx):
...
Above are the ones that need changing.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论