如何防止在重新加载齿轮后出现 AttributeError?
How can I prevent getting an AttributeError after reloading a cog?
今天有一个比较不寻常的问题,但也许有人可以帮助我。
我正在开发一个与音乐有关的机器人。以下问题:
如果我在 cog
中更改内容,然后在 reload
中更改内容,我总是会收到特定命令的 AttributeError: 'NoneType' object has no attribute 'XXXX'
错误。 有办法fix/prevent吗?
例如,当机器人在语音通道中时发生错误,然后我重新加载cog
。
我查询 state
每个与音乐有关的命令,它可能与那个有关吗?
state = self.get_state(ctx.guild)
get_state
的完整功能:
def get_state(self, guild):
"""Gets the state for `guild`, creating it if it does not exist."""
if guild.id in self.states:
return self.states[guild.id]
else:
self.states[guild.id] = GuildState()
return self.states[guild.id]
我尝试 用 try/except AttributeError
解决它,但当然那不是真的 work/the 控制台仍然给了我输出。
示例代码如下:
@commands.command()
@commands.guild_only()
@commands.check(audio_playing)
@commands.check(in_voice_channel)
@commands.check(is_audio_requester)
async def loop(self, ctx):
"""Activates/Deactivates the loop for a song."""
state = self.get_state(ctx.guild)
status = state.now_playing.toggle_loop()
if status is None:
return await ctx.send(
embed=discord.Embed(title=":no_entry: Unable to toggle loop.", color=discord.Color.red()))
else:
return await ctx.send(embed=discord.Embed(
title=f":repeat: Loop: {'**Enabled**' if state.now_playing.loop else '**Disabled**'}.",
color=self.bot.get_embed_color(ctx.guild)))
如果我在 cog
中进行更改,请重新加载它,然后再次尝试 运行 loop
我会收到以下 错误 :
In loop:
File "C:\Users\Dominik\PycharmProjects\AlchiReWrite\venv\lib\site-packages\discord\ext\commands\core.py", line 85, in wrapped
ret = await coro(*args, **kwargs)
File "C:\Users\Dominik\PycharmProjects\AlchiReWrite\cogs\music.py", line 220, in loop
status = state.now_playing.toggle_loop()
AttributeError: 'NoneType' object has no attribute 'toggle_loop'
(所有其他命令都出现同样的错误)
请教,我们有GuildState
class:
class GuildState:
"""Helper class managing per-guild state."""
def __init__(self):
self.volume = 1.0
self.playlist = []
self.message_queue = []
self.skip_votes = set()
self.now_playing = None
self.control_message = None
self.loop = False
self.skipped = False
def is_requester(self, user):
return self.now_playing.requested_by == user
我该如何克服这个错误?
机器人加入命令 play URL
然后我构建了以下内容:
if not state.now_playing:
self._play_song(client, state, video)
_play_song
主要定义如下:
def _play_song(self, client, state, song):
state.now_playing = song
# Other things are not relevant
重新加载 cog 时,cog 中的 states
字典将为空。使用 state = self.get_state(ctx.guild)
,将创建一个新的 GuildState
对象。从GuildState
class的__init__
函数中,self.now_playing
设置为None
。
因此,status = state.now_playing.toggle_loop()
将抛出一个 AttributeError
,因为 None
没有属性(在这种情况下,没有 toggle_loop
属性)。
如果您想消除这些错误,您需要将 self.now_playing
正确设置为具有所需属性的内容。
如果你想保持 states
字典不变,你可以在重新加载你的 cog 之前保存它并恢复它。下面的例子假设 cog class 被命名为 TestCog
.
@client.command()
async def reload(ctx):
temp = client.get_cog('TestCog').states
client.reload_extension('cog')
client.get_cog('TestCog').states = temp
请注意,如果您更改 GuildState
的创建方式,这可能会破坏您的齿轮,因为您正在恢复 states
的先前版本。
今天有一个比较不寻常的问题,但也许有人可以帮助我。
我正在开发一个与音乐有关的机器人。以下问题:
如果我在 cog
中更改内容,然后在 reload
中更改内容,我总是会收到特定命令的 AttributeError: 'NoneType' object has no attribute 'XXXX'
错误。 有办法fix/prevent吗?
例如,当机器人在语音通道中时发生错误,然后我重新加载cog
。
我查询 state
每个与音乐有关的命令,它可能与那个有关吗?
state = self.get_state(ctx.guild)
get_state
的完整功能:
def get_state(self, guild):
"""Gets the state for `guild`, creating it if it does not exist."""
if guild.id in self.states:
return self.states[guild.id]
else:
self.states[guild.id] = GuildState()
return self.states[guild.id]
我尝试 用 try/except AttributeError
解决它,但当然那不是真的 work/the 控制台仍然给了我输出。
示例代码如下:
@commands.command()
@commands.guild_only()
@commands.check(audio_playing)
@commands.check(in_voice_channel)
@commands.check(is_audio_requester)
async def loop(self, ctx):
"""Activates/Deactivates the loop for a song."""
state = self.get_state(ctx.guild)
status = state.now_playing.toggle_loop()
if status is None:
return await ctx.send(
embed=discord.Embed(title=":no_entry: Unable to toggle loop.", color=discord.Color.red()))
else:
return await ctx.send(embed=discord.Embed(
title=f":repeat: Loop: {'**Enabled**' if state.now_playing.loop else '**Disabled**'}.",
color=self.bot.get_embed_color(ctx.guild)))
如果我在 cog
中进行更改,请重新加载它,然后再次尝试 运行 loop
我会收到以下 错误 :
In loop:
File "C:\Users\Dominik\PycharmProjects\AlchiReWrite\venv\lib\site-packages\discord\ext\commands\core.py", line 85, in wrapped
ret = await coro(*args, **kwargs)
File "C:\Users\Dominik\PycharmProjects\AlchiReWrite\cogs\music.py", line 220, in loop
status = state.now_playing.toggle_loop()
AttributeError: 'NoneType' object has no attribute 'toggle_loop'
(所有其他命令都出现同样的错误)
请教,我们有GuildState
class:
class GuildState:
"""Helper class managing per-guild state."""
def __init__(self):
self.volume = 1.0
self.playlist = []
self.message_queue = []
self.skip_votes = set()
self.now_playing = None
self.control_message = None
self.loop = False
self.skipped = False
def is_requester(self, user):
return self.now_playing.requested_by == user
我该如何克服这个错误?
机器人加入命令 play URL
然后我构建了以下内容:
if not state.now_playing:
self._play_song(client, state, video)
_play_song
主要定义如下:
def _play_song(self, client, state, song):
state.now_playing = song
# Other things are not relevant
重新加载 cog 时,cog 中的 states
字典将为空。使用 state = self.get_state(ctx.guild)
,将创建一个新的 GuildState
对象。从GuildState
class的__init__
函数中,self.now_playing
设置为None
。
因此,status = state.now_playing.toggle_loop()
将抛出一个 AttributeError
,因为 None
没有属性(在这种情况下,没有 toggle_loop
属性)。
如果您想消除这些错误,您需要将 self.now_playing
正确设置为具有所需属性的内容。
如果你想保持 states
字典不变,你可以在重新加载你的 cog 之前保存它并恢复它。下面的例子假设 cog class 被命名为 TestCog
.
@client.command()
async def reload(ctx):
temp = client.get_cog('TestCog').states
client.reload_extension('cog')
client.get_cog('TestCog').states = temp
请注意,如果您更改 GuildState
的创建方式,这可能会破坏您的齿轮,因为您正在恢复 states
的先前版本。