Команда вызвала исключение: Ошибка атрибута: объект «Контекст» не имеет атрибута «идентификатор» discord.py

#python #discord.py

Вопрос:

Я хочу удалить идентификатор Гильдии в файле JSON с помощью команды.

Это мой код:

  @welcome.command(pass_context=True)
    @commands.has_permissions(administrator=True)
    async def reset(guild):
        with open('welcome.json', 'r') as f:
            welcome = json.load(f)
    
        welcome.pop(str(guild.id))
        with open('welcome.json', 'w',) as f:
            json.dump(welcomereset, f, indent=4)
 

Это сообщение об ошибке: discord.ext.команды.ошибки.CommandInvokeError: Команда вызвала исключение: Ошибка атрибута: объект «Контекст» не имеет атрибута «идентификатор»

Как я могу это исправить?

Ответ №1:

  @welcome.command() #pass_context is deprecated, every command will always get passes Context as first param.
 @commands.has_permissions(administrator=True)
 async def reset(ctx: commands.Context): #Just normal typehint for you to easily understand.
        with open('welcome.json', 'r') as f:
            welcome = json.load(f)
    
        welcome.pop(str(ctx.guild.id)) #ctx.guild -> discord.Guild and than .id for it's id. I would put an if statement to check if the command was even in a guild, so NoneType attribute error won't raise.
        with open('welcome.json', 'w',) as f:
            json.dump(welcomereset, f, indent=4)
 

Первым параметром в каждой команде является ctx или контекст, представляющий команды discord.ext.Объект контекста, который, как вы можете видеть, не имеет идентификатора. Если вы пытаетесь получить идентификатор гильдии, где была вызвана команда, выполнение ctx.guild вернет необязательный[discord.Гильдия](если команда была вызвана в частном канале). И чем, если это не так, вы можете заняться ctx.guild.id, что, вероятно, и есть то, чего вы хотите. И вам больше не нужен pass_context(который использовался для передачи команд discord.ext.Контекст, кстати). Что означает, что прямо сейчас гильдия является вашим контекстным объектом.

Ответ №2:

Первым параметром в каждой команде является ctx или context представляет команды discord.ext.Объект контекста, которого, как вы можете видеть, нет id . Если вы пытаетесь получить идентификатор гильдии, где была вызвана команда, выполнение ctx.guild вернет необязательный[discord.Гильдия](если команда была вызвана в частном канале). И чем, если это не так, вы можете заняться ctx.guild.id, что, вероятно, и есть то, чего вы хотите. И вам больше не нужно pass_context (что использовалось для передачи команд discord.ext.Контекст кстати)

Комментарии:

1. Что означает, что прямо сейчас- guild это ваш контекстный объект.

Ответ №3:

Поскольку вы не упомянули о своем discord.py версия, я полагаю:

— Это было до версии 1.0:

У вас есть pass_context=True , поэтому контекст будет передан в качестве первого аргумента в функции.

 async def reset(guild): # The word 'guild' is actually a Context object
 

Имя guild определяется как Контекст, поэтому, независимо от имени, оно следует свойствам Контекста, а не Гильдии. Поэтому вы все еще можете использовать guild свойства контекста и следовать им, но рекомендуется отредактировать guild context их или ctx предотвратить путаницу.

Вы также можете просто сделать pass_context=False и сделать guild так, чтобы аргумент был принят в качестве входных данных через пользователя.

— Это после версии 1.0:

С тех pass_context пор параметр удален, поэтому независимо от того, используете вы его или нет, контекст всегда передается.

Как и выше, вам необходимо следовать свойствам контекста и использовать соответствующие атрибуты. В вашем случае, если вам нужно получить доступ к идентификатору гильдии, вызывается команда, которую вы можете выполнить ctx.guild.id ( ctx относится к переданному объекту контекста).

 async def reset(ctx):
    ...
    welcome.pop(str(ctx.guild.id))
    ...
 

и это будет работать нормально.

P.S.: Я не уверен, но, посмотрев на код, я думаю, что вы передали неправильный аргумент ( welcomereset ) в .dump() и хотите передать welcome вместо этого. Игнорируйте это, если я ошибаюсь 😛

Комментарии:

1. Спасибо, и да, вы правы, я также передал в нем неверный аргумент xD