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

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

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

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

Q&A

解決済

2回答

1857閲覧

Pythonのexcept 節とrepr()がわかりません

退会済みユーザー

退会済みユーザー

総合スコア0

Python

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

0グッド

0クリップ

投稿2021/10/01 10:30

Pythonのexcept節とrepr()がわかりません。
以下のプログラムは自分がネットで見つけたプログラムの1部です。

具体的にわからない点を書きます。
except節について
例外処理のtryについてはこちらのサイトで

Pythonで例外(実行中に検出されたエラー)をキャッチして処理するにはtry, exceptを使う。

とありました。Pythonの例外処理!try-exceptをわかりやすく解説!では

try:

例外が発生するかもしれないが、実行したい処理。

except エラー名:
例外発生時に行う処理

まずは、tryの中に指定された処理が実行されます。例外が発生しなければ、except文はスキップされます。

tryブロック内で「raise」句を使用して故意に例外を発生させ、「except」ブロックで例外を捉え「故意にエラーを発生」と表示させています。

try実行中にexceptキーワードの後に指定したエラー名と一致する例外が発生すると、except文が実行され、それ以降に記述された処理も実行されます。

とありました。
しかし、参考にしているプログラムではexceptの後にraiseがあります。
どういう処理になるのでしょうか?
また、Exceptionはどのようなえらーなのでしょうか?

repr()でわからないこと
こちらのサイトで、

repr() メソッドを定義することで、この関数によりそのクラスのインスタンスが返すものを制御することができます。

repr() メソッドを定義することで、この関数によりそのクラスのインスタンスが返すものを制御することができます。

とありました。また、同じサイトで

object.str(self)

オブジェクトの「非公式の (informal)」あるいは表示に適した文字列表現を計算するために、 str(object) と組み込み関数 format(), print() によって呼ばれます。戻り値は string オブジェクトでなければなりません。
str() が有効な Python 表現を返すことが期待されないという点で、このメソッドは object.repr() とは異なります: より便利な、または簡潔な表現を使用することができます。

とあります。

def str(self):

return repr(self.value)

の処理はどうなるのでしょうか?

python

1class IOException(Exception): 2 #__int__(self):int()関数を使うときに呼び出されるメソッド 3 def __init__(self, value): 4 self.value = value 5 #__str__(self):str()関数,組み込み関数 format(), print() を使うときに呼び出されるメソッド 6 def __str__(self): 7 #repr()は引数付きのコンストラクタ(または初期化子)を文字列で返してくれる関数 8 return repr(self.value)

python

1 2# 露出補正された8ビット画像を書き込む 3def writeLDR(img, file, exposure=0): 4 5 # 線形領域の露出fstopを表示値の倍率に変換します 6 sc = np.power(np.power(2.0, exposure), 0.5) 7 8 try: 9 scipy.misc.toimage(sc*np.squeeze(img), cmin=0.0, cmax=1.0).save(file) 10 except Exception as e: 11 raise IOException("Failed writing LDR image: %s"%e)

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

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

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

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

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

y_waiwai

2021/10/01 10:31

そのサイトを提示しましょう
ikapy

2021/10/01 10:56

「except」と「repr」は全く別物なので(exceptとreprは関連性がない)、「except」と「repr」の別々の質問を立てる方が良いと思います。理由は回答が発散するのでは危惧するからです。
guest

回答2

0

質問文中で引用されているサイト(https://www.sejuku.net/blog/23044)の間違った記述のために、無用な混乱をさせられていることが理解の妨げになっていると思いますので、それを先に指摘しておきます。

「例外が発生した後の処理とは」と題して、

「except」ブロックで実行する処理は、様々なパターンがあるのでそれぞれご紹介していきたいと思います

と言っておきながら、

故意に例外を起こす場合は「raise」句を使用します。

以下のサンプルコードをご覧ください。

try:
raise ZeroDivisionError
except:
print('故意にエラーを発生')

と文章が続くのはおかしいと思いませんか?
この流れなら、except 節に raise 文のあるサンプルコードを示して、その説明をするべきでしょう。なぜ try 節に raise 文のあるコードが示されているのでしょうか(さらにいえば raise は文であって句ではありません)。

上記のコードは Python の文法的には有効なコードですが、try 文を使った処理パターンを説明するという目的からいえば、間違い(あるいは場違い)と言っていいと思います。

ついでに言えばそのサイトの冒頭で

Pythonではtry-exceptで「例外処理(exception)」を記述しておくことで、予期せぬエラーを未然に防ぐことができます

と書かれているのも間違いですね。
try 文で行われているのは、発生が予想されるエラー(例外)に対して、そのエラーが発生した際の処理を書いておくことです。予期できないエラーを未然に防ぐことはできません。当然ですね。さらに言えば「例外処理(exception)」と書かれていますが exception は例外であって例外処理ではありません。

さて、try 文を使った処理パターンとして、(try 節ではなく)except 節で raise 文が実行されるパターンは実際にあります。問題となっている
https://github.com/gabrieleilertsen/hdrcnn/blob/master/img_io.py
のコードも、そのひとつということになります。

except 節で raise 文が実行されるパターンで行われていることは、「try 節で例外を捕捉した後に、いったん何らかの処理を経た上で、例外を送出し直してプログラムを終了する」です。
except 節で行われる処理が、その「何らかの処理」ということになります。
最終的に送出される例外は、try 節で発生した例外をそのまま送出しなおすこともできますし、それとは別の例外を送出することもできます。別の例外を送出した場合は try 節で発生した例外も同時に送出されますが、これを隠すこともできます。

except 節でどのような処理を行うかは、プログラムによっていろいろでしょうが、問題になっているプログラムの場合を具体的に見てみましょう。

python

1class IOException(Exception): 2 def __init__(self, value): 3 self.value = value 4 def __str__(self): 5 return repr(self.value) 6 7... 8 9def writeLDR(img, file, exposure=0): 10 ... 11 12 try: 13 scipy.misc.toimage(sc*np.squeeze(img), cmin=0.0, cmax=1.0).save(file) 14 except Exception as e: 15 raise IOException("Failed writing LDR image: %s"%e)

https://github.com/gabrieleilertsen/hdrcnn/blob/master/img_io.py

このコードでは、最終的に送出されている例外は、ユーザ定義例外である IOException です。
例外の送出の前に行われている処理は特にありませんので、このコードの場合はユーザ定義例外の送出自体が「何らかの処理」ということになります。
ユーザ定義例外 IOException では、try 節で捕捉された例外のエラーメッセージを、自らのエラーメッセージの一部に取り込んでいます。

このコードで実際にどのようなエラーメセージが表示されるかを示すために、次のような内容のサンプルモジュール raise_test.py を用意しました。

python

1class IOException(Exception): 2 def __init__(self, value): 3 self.value = value 4 def __str__(self): 5 return repr(self.value) 6 7def writeLDR(): 8 try: 9 1/0 10 except Exception as e: 11 raise IOException("Failed writing LDR image: %s"%e)

このモジュールを読み込んでwriteLDR関数を実行した結果は次のようになります。

python

1>>> import raise_test 2>>> raise_test.writeLDR() 3Traceback (most recent call last): 4 File "/Users/xxxx/raise_test.py", line 12, in writeLDR 5 1/0 6ZeroDivisionError: division by zero 7 8During handling of the above exception, another exception occurred: 9 10Traceback (most recent call last): 11 File "<stdin>", line 1, in <module> 12 File "/Users/xxxx/raise_test.py", line 14, in writeLDR 13 raise IOException("Failed writing LDR image: %s"%e) 14raise_test.IOException: 'Failed writing LDR image: division by zero'

このように、当初 try 節で発生した例外と、except 節で raise した例外の両方が、同時に送出されています。

念のためコードの動きをひとつひとつ見ていくと、

  1. scipy.misc.toimage(sc*np.squeeze(img), cmin=0.0, cmax=1.0).save(file)の実行で例外が発生すると、その例外は補足され、except節に実行が移ります。
  2. except Exceptionとありますので、捕捉される例外は、SystemExitやKeyboardInterruptなどを除いた、ほぼすべての例外です。なぜここで Exception を入れたのかというと、発生した例外をas eで取得して、except 節での処理で使いたかったからだと思います。何らかの具体的な例外クラス名を指定しないと、as 構文は使えませんので。
  3. except Exception as eにより、変数eに try 節で発生した例外の例外オブジェクトが代入されます。
  4. "Failed writing LDR image: %s"%eにより、e に代入されている例外オブジェクトの__str__メソッドの返す値が、IOExceptionのエラーメッセージの一部(%s の位置)に組み込まれます。例外オブジェクトの__str__メソッドの返す値とは、その例外のエラーメッセージです。
  5. IOException("Failed writing LDR image: %s"%e)により、ユーザ定義例外であるIOExceptionがインスタンス化されます。
  6. raise IOException("Failed writing LDR image: %s"%e) により IOException 例外が送出されます。try 節で捕捉された例外もこのとき同時に再送出されます。

なぜこのような例外処理の方法を選んだのかは、このプログラムを書いた当人に聞いてみないとわかりません。上のようにした方が多少なりともユーザフレンドリだと思ったからかもしれませんし、Pythonの例外処理の書き方を学習した時にそのようなパターンで覚えたからそれをそのまま踏襲しているだけかもしれません。実際のところはわかりません。

ちなみに、
raise IOException(...)
とせずに単に
raise
とすると、try 節で捕捉された最初の例外がそのまま再送出されます。「式を伴わなければ、 raise は現在のスコープで最終的に有効になっている例外を再送出します」とはそういう意味です。

python

1>>> try: 2... 1/0 3... except: 4... raise 5... 6Traceback (most recent call last): 7 File "<stdin>", line 2, in <module> 8ZeroDivisionError: division by zero

投稿2021/10/04 05:03

etherbeg

総合スコア1195

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

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

0

ベストアンサー

  • しかし、参考にしているプログラムではexceptの後にraiseがあります。

どういう処理になるのでしょうか?

書かれているサイトではraiseを勉強する前に、try-exceptをちゃんと理解しなければならないのに、一体であるかのように書いてありますね。
説明が下手なのでわかりにくいと思います。
Pythonの例外処理(try, except, else, finally)の方が良いでしょう。

  • Exceptionはどのようなえらーなのでしょうか?

「実行中に検出されたエラー」を知らせるためのものです。

ikapyさんも書かれていますが、一つの質問では内容は一つにすべきだと考えていますので、「repr()でわからないこと」に対しては回答しません。

投稿2021/10/01 11:19

ppaul

総合スコア24666

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

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

退会済みユーザー

退会済みユーザー

2021/10/01 12:00

> Exceptionはどのようなえらーなのでしょうか? 「実行中に検出されたエラー」を知らせるためのものです。 とあるのですが、 try: scipy.misc.toimage(sc*np.squeeze(img), cmin=0.0, cmax=1.0).save(file) で何かエラーがが検出されたら、Exceptionというエラーになって except Exception as e: raise IOException("Failed writing LDR image: %s"%e) が実行されるのですか?
退会済みユーザー

退会済みユーザー

2021/10/03 07:06

> 参考にしているプログラムではexceptの後にraiseがあります。 どういう処理になるのでしょうか? で、サイトを読み返したのですがわかりませんでした。 基底クラスException システム終了(SystemExit, KeyboardInterruptなど)以外のすべての組み込み例外の基底クラスであるExceptionをexcept節に指定する方法がある。 となっていたので、殆んどの例外を対象としていることはわかりました。 こちらのサイトにはraiseは https://atmarkit.itmedia.co.jp/ait/articles/1909/10/news013.html raise文  例外を送出するにはraise文を使用する。 とありました。 さらに、 https://docs.python.org/ja/3/reference/simple_stmts.html#the-raise-statement では、 式を伴わなければ、 raise は現在のスコープで最終的に有効になっている例外を再送出します。そのような例外が現在のスコープでアクティブでない場合、 RuntimeError 例外が送出されて、これがエラーであることを示します。 とありました。 結局 except Exception as e: raise IOException("Failed writing LDR image: %s"%e) の処理はどういうものなのでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問