PythonでDiscord bot 「5.トピック紹介(2)try~except」

スポンサーリンク

こんにちは。今回は「try~except」を紹介します。
使えるようになると強力な武器になります。私のbotでも山のように使われています。
それでは早速始めましょう。

(2)try~except

①基本

始めに、基本となるコードです。

 if message.content.startswith('k1/moji'):
  msg = message.content.split()
  try:
   await message.channel.send(str(msg[1]))
  except IndexError:
   await message.channel.send("文字列の指定がありません。")

try~exceptは、「try以下を試してエラーがなければそのまま実行」「〇というエラーが起こったら『except 〇エラー以降』を実行」という命令になります。
わかりにくいので実際に上の例でプログラムを走らせてみます。

5.トピック紹介(1)split」で説明した通り、上のコードのmsg[1]には「hello」が格納され、それがそのまま返ります。tryでエラーが出なかった例です。次はどうでしょうか。

この場合、msg[1]に該当する文字列が存在しません。Pythonでは、「IndexError」というエラーが発生しています。上のコードに戻りましょう。

 if message.content.startswith('k1/moji'):
  msg = message.content.split()
  try:
   await message.channel.send(str(msg[1]))
  except IndexError:
   await message.channel.send("文字列の指定がありません。")

tryの1行下で実行したコードが 「IndexError」 のため、except以降の命令が実行されます。
(ここでは、「文字列の指定がありません。」が返ります。)

②エラー指定について

「except IndexError:」とした場合、「IndexError」のみに反応しますが、以下のように複数並べることが可能です。

  except ●●Error:
   〇〇
  except ■■Error:
   □□

また、エラーを何も書かない場合、あらゆるエラーに対してその下のコードが実行されます。
どんなエラーが出てもエラー回避できるのでとても便利ですが、反面、どんなエラーが出ているか見えないという弱点もあります。これについては③で補足します。

③traceback.print_exc()

try~exceptは非常に強力ですが、どんなエラーが発生しているか見えなくなり、プログラムのデバッグなどで困る場面が出てきます。そこで登場するのが「traceback.print_exc()」です。
コードを掲載します。

import discord
import datetime
import traceback

client = discord.Client()

#起動時のshellメッセージ 
@client.event
async def on_ready():
       print('Logged in as')
       print('BOT-NAME :', client.user.name)
       print('BOT-ID   :', client.user.id)
       print('Time     :', datetime.datetime.now())
       print('------')


@client.event
async def on_message(message):

 if client.user == message.author:
   return

 if message.content.startswith('k1/moji'):
  msg = message.content.split()
  try:
   await message.channel.send(str(msg[1]))
  except:
   await message.channel.send("文字列の指定がありません。")
   traceback.print_exc()

まず、冒頭で「import traceback」によりパッケージをインポートしてください。
そして、except命令の最後に、「traceback.print_exc()」と追加します。
そして、エラーが出るようなコマンドを打ってみると・・・?

以下のようにエラーメッセージが表示されるようになります。

④try~exceptの何が便利なのか?

ここまでご覧になっても、この関数の何が便利なのかよくわからない、という方もいらっしゃるかと思います。この関数は、エラー制御に使うだけでなく、以下のような使い方もできるところがミソです。

◆ユーザーに任意の秒数を指定させる(例:msg[1]に120を格納する)
◆秒数指定がない場合、60秒を自動指定する(例:IndexErrorになったら60を使用する)

百聞は一見に如かずです。是非色々試してみてください!
今回はここまでです。次回をお楽しみに!

最後に~寄付のお願い~

私のbotは、無償で開発しています。また、稼働しているサーバー代が毎月かかっており、完全持ち出しの状況です。もし寄付してもいいよ、という方がいらっしゃいましたらよろしくお願いいたします。リンク先はMONAの寄付ですが、他の通貨でのご寄付をいただける場合は私までご連絡いただけると大変ありがたいです。 (私、こげさんは「アルファDIscord」にいます。)
ほしいMONAリスト (komikikaku.com)

よろしければ記事のシェアをお願いします!