質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

2532閲覧

Discord.pyのNoneTypeエラー、

White07

総合スコア1

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/08/06 10:36

前提・実現したいこと

Discord.pyで同じ名前のテキストチャンネルとボイスチャンネルを作り、2つの名前をコマンドで編集したり、削除したりする機能を作りたいです。 テキストチャンネルは編集、削除が出来ますが、ボイスチャンネルの方でエラーが発生しています。
編集用のコマンドと削除用のコマンドでエラーが発生しています。

発生している問題・エラーメッセージ

#編集用のコマンドで発生しているエラー discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: 'NoneType' object has no attribute 'edit' #削除用のコマンドで発生しているエラー discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: 'NoneType' object has no attribute 'delete'

該当のソースコード

python

1#チャンネル作成 2@bot.command() 3async def create(ctx, name = '部屋'): 4 Guild = bot.get_guild(836935048359182359) 5 category= bot.get_channel(872803559572398081) 6 channel = Guild.get_channel(873062525124624474) 7 if ctx.channel.id == 873062525124624474: 8 await Guild.create_text_channel(name, category = category) 9 await Guild.create_voice_channel(name, category = category, user_limit = 3) 10 await channel.send(f'{ctx.author.mention}さんが「{name}」を作りました。') 11 else: 12 channel = ctx.message.channel 13 embed=discord.Embed(title="このチャンネルでは`s!create [name]`は使用できません。", description="このメッセージとコマンドは数秒後に削除されます。", color=0xff0000) 14 message = await channel.send(embed=embed) 15 await asyncio.sleep(10) 16 await message.delete() 17 18 19#チャンネル編集 20@bot.command() 21async def edit(ctx, new_name = ''): 22 if ctx.channel.category_id == 872803559572398081 and ctx.channel.id != 873062525124624474: 23 guild = bot.get_guild(836935048359182359) 24 channel1 = ctx.message.channel 25 v_channel = discord.utils.get(guild.voice_channels, name=channel1) 26 await channel1.edit(name = new_name) 27 await v_channel.edit(name = new_name) 28 await channel1.send(f'チャンネル名を「{new_name}」に変更しました。') 29 elif new_name == '': 30 channel = ctx.message.channel 31 embed=discord.Embed(title="変更したい名前[new_name]を入力してください。", description="このメッセージとコマンドは数秒後に削除されます。", color=0xff0000) 32 message = await channel.send(embed=embed) 33 await asyncio.sleep(10) 34 await message.delete() 35 else: 36 channel2 = ctx.message.channel 37 embed=discord.Embed(title="このチャンネルでは`s!edit [new_name]`は使用できません。", description="このメッセージとコマンドは数秒後に削除されます。", color=0xff0000) 38 message = await channel2.send(embed=embed) 39 await asyncio.sleep(10) 40 await message.delete() 41#チャンネル削除 42@bot.command() 43async def delete(ctx): 44 if ctx.channel.category_id == 872803559572398081 and ctx.channel.id != 873062525124624474: 45 guild = bot.get_guild(836935048359182359) 46 channel = ctx.message.channel 47 v_channel = discord.utils.get(guild.voice_channels, name=channel) 48 await channel.delete() 49 await v_channel.delete() 50 channel1 = guild.get_channel(873062525124624474) 51 await channel1.send(f'{ctx.author.mention}さんが「{channel}」を削除しました。') 52 else: 53 channel = ctx.message.channel 54 embed=discord.Embed(title="このチャンネルでは`s!delete`は使用できません。", description="このメッセージとコマンドは数秒後に削除されます。", color=0xff0000) 55 message = await channel.send(embed=embed) 56 await asyncio.sleep(10) 57 await message.delete() 58 59bot.run(config.TOKEN)

試したこと

Channel ID、 Guild ID の確認

補足情報(FW/ツールのバージョンなど)

Discord.py 1.7.3

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

試せる環境が今無いので、あまり細かくは分からないですが…

エラーについては、messageオブジェクトなりchannelオブジェクトだと思っているものに、edit()なりdelete()なりのメソッドを実行しようとした際、実はそれはNoneTypeオブジェクトなので「そういうメソッドは無いよ」と言われてる訳ですね。
コードを見る限りでは…・取得できてるように思うのですが…できてないのでしょうね。

message = await channel.send(embed=embed)
channel = ctx.message.channel
こういうのがNoneになるパターンって、あまり思いつかないんですよね。

ただ、実際そうなっているんでしょうから、エラーが出る行の直前でそのオブジェクトが何であるか確認し(まあNoneなんですけど)、どうしてNoneなのかコードを追ってみるしかないですね。

で、少し気になる事があるので指摘します。

editdeleteという関数名は混乱の元ですのでやめた方がいいです。
関数名は、それだけで何をする関数か分かるように書くのが基本です。
コマンド名としてそれらを使いたいという事であれば、

python

1@bot.command(name='edit') 2async def edit_channel_name(ctx, arg):

のように書けます。
これであれば関数名はedit_channel_nameですがコマンドとしてはeditで動作します。

たまたまエラーになっているメソッドがedit()delete()ですので関連があるのか?と考えてしまいますが、(多分)そこは関係ないです。
でも、結局そういう事も頭によぎるので、考える事が一つ増えちゃいますよね。そういうのが混乱という事です。

それと、message.delete()の前にsleep()していますが、こうやるとsleep中に状態が変わって削除に失敗すると(例えば先に手動削除された等)エラーになります。
これはdelete()の引数で
await delete(delay=10)
のように書けます(削除の実行を指定時間遅延させる)。
もし、削除に失敗した場合は黙って握りつぶしてくれますので他に影響が出ません。

あまり回答になっていませんが、何をした時どの行でどうしてエラーになっているのかを調査してみて下さい。

投稿2021/08/06 15:24

udon-ken

総合スコア657

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

一度、全て書き直しました。udon-kenさんの回答の中に合った

@bot.command(name='edit') async def edit_channel_name(ctx, arg):

のように書いたらエラーも吐かれずに出来ました。ありがとうございました。

投稿2021/08/07 13:20

White07

総合スコア1

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問