Repository navigation
Expand file tree
/
Copy patherrors.html
More file actions
431 lines (408 loc) · 51 KB
/
Copy patherrors.html
File metadata and controls
431 lines (408 loc) · 51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>8. エラーと例外 — Python 2.7.14 ドキュメント</title>
<link rel="stylesheet" href="../_static/classic.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '../',
VERSION: '2.7.14',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<script type="text/javascript" src="../_static/translations.js"></script>
<script type="text/javascript" src="../_static/sidebar.js"></script>
<link rel="search" type="application/opensearchdescription+xml"
title="Python 2.7.14 ドキュメント 内を検索"
href="../_static/opensearch.xml"/>
<link rel="author" title="このドキュメントについて" href="../about.html" />
<link rel="index" title="索引" href="../genindex.html" />
<link rel="search" title="検索" href="../search.html" />
<link rel="copyright" title="Copyright" href="../copyright.html" />
<link rel="next" title="9. クラス" href="classes.html" />
<link rel="prev" title="7. 入力と出力" href="inputoutput.html" />
<link rel="shortcut icon" type="image/png" href="../_static/py.png" />
<link rel="canonical" href="https://docs.python.jp/3/tutorial/errors.html" />
<script type="text/javascript" src="../_static/copybutton.js"></script>
<script type="text/javascript" src="../_static/_jp.js"></script>
<script type="text/javascript" src="../_static/version_switch.js"></script>
</head>
<body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>ナビゲーション</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="総索引"
accesskey="I">索引</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Pythonモジュール索引"
>モジュール</a> |</li>
<li class="right" >
<a href="classes.html" title="9. クラス"
accesskey="N">次へ</a> |</li>
<li class="right" >
<a href="inputoutput.html" title="7. 入力と出力"
accesskey="P">前へ</a> |</li>
<li><img src="../_static/py.png" alt=""
style="vertical-align: middle; margin-top: -1px"/></li>
<li><a href="http://www.python.jp/">Python</a> »</li>
<li>
<span class="version_switcher_placeholder">2.7.14</span>
<a href="../index.html">ドキュメント</a> »
</li>
<li class="nav-item nav-item-1"><a href="index.html" accesskey="U">Python チュートリアル</a> »</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="errors-and-exceptions">
<span id="tut-errors"></span><h1>8. エラーと例外<a class="headerlink" href="#errors-and-exceptions" title="このヘッドラインへのパーマリンク">¶</a></h1>
<p>これまでエラーメッセージについては簡単に触れるだけでしたが、チュートリアル中の例を自分で試していたら、実際にいくつかのエラーメッセージを見ていることでしょう。エラーには (少なくとも) 二つのはっきり異なる種類があります。それは <em>構文エラー (syntax error)</em> と <em>例外 (exception)</em> です。</p>
<div class="section" id="syntax-errors">
<span id="tut-syntaxerrors"></span><h2>8.1. 構文エラー<a class="headerlink" href="#syntax-errors" title="このヘッドラインへのパーマリンク">¶</a></h2>
<p>構文エラーは構文解析エラー (parsing error) としても知られており、Python を勉強している間に最もよく遭遇する問題の一つでしょう:</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="k">while</span> <span class="kc">True</span> <span class="nb">print</span> <span class="s1">'Hello world'</span>
File <span class="nb">"<stdin>"</span>, line <span class="m">1</span>
<span class="k">while</span> <span class="kc">True</span> <span class="nb">print</span> <span class="s1">'Hello world'</span>
<span class="o">^</span>
<span class="gr">SyntaxError</span>: <span class="n">invalid syntax</span>
</pre></div>
</div>
<p>パーサは違反の起きている行を表示し、小さな「矢印」を表示して、行中でエラーが検出された最初の位置を示します。エラーは矢印の <em>直前の</em> トークンでひき起こされています (または、少なくともそこで検出されています)。上記の例では、エラーは <a class="reference internal" href="../reference/simple_stmts.html#print"><code class="xref std std-keyword docutils literal"><span class="pre">print</span></code></a> で検出されています。コロン (<code class="docutils literal"><span class="pre">':'</span></code>) がその前に無いからです。入力がスクリプトから来ている場合は、どこを見ればよいか分かるようにファイル名と行番号が出力されます。</p>
</div>
<div class="section" id="exceptions">
<span id="tut-exceptions"></span><h2>8.2. 例外<a class="headerlink" href="#exceptions" title="このヘッドラインへのパーマリンク">¶</a></h2>
<p>たとえ文や式が構文的に正しくても、実行しようとしたときにエラーが発生するかもしれません。実行中に検出されたエラーは <em>例外 (exception)</em> と呼ばれ、常に致命的とは限りません。これから、Python プログラムで例外をどのように扱うかを学んでいきます。ほとんどの例外はプログラムで処理されず、以下に示されるようなメッセージになります:</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="mi">10</span> <span class="o">*</span> <span class="p">(</span><span class="mi">1</span><span class="o">/</span><span class="mi">0</span><span class="p">)</span>
<span class="gt">Traceback (most recent call last):</span>
File <span class="nb">"<stdin>"</span>, line <span class="m">1</span>, in <span class="n"><module></span>
<span class="gr">ZeroDivisionError</span>: <span class="n">integer division or modulo by zero</span>
<span class="gp">>>> </span><span class="mi">4</span> <span class="o">+</span> <span class="n">spam</span><span class="o">*</span><span class="mi">3</span>
<span class="gt">Traceback (most recent call last):</span>
File <span class="nb">"<stdin>"</span>, line <span class="m">1</span>, in <span class="n"><module></span>
<span class="gr">NameError</span>: <span class="n">name 'spam' is not defined</span>
<span class="gp">>>> </span><span class="s1">'2'</span> <span class="o">+</span> <span class="mi">2</span>
<span class="gt">Traceback (most recent call last):</span>
File <span class="nb">"<stdin>"</span>, line <span class="m">1</span>, in <span class="n"><module></span>
<span class="gr">TypeError</span>: <span class="n">cannot concatenate 'str' and 'int' objects</span>
</pre></div>
</div>
<p>エラーメッセージの最終行は何が起こったかを示しています。例外は様々な型 (type) で起こり、その型がエラーメッセージの一部として出力されます。上の例での型は <a class="reference internal" href="../library/exceptions.html#exceptions.ZeroDivisionError" title="exceptions.ZeroDivisionError"><code class="xref py py-exc docutils literal"><span class="pre">ZeroDivisionError</span></code></a>, <a class="reference internal" href="../library/exceptions.html#exceptions.NameError" title="exceptions.NameError"><code class="xref py py-exc docutils literal"><span class="pre">NameError</span></code></a>, <a class="reference internal" href="../library/exceptions.html#exceptions.TypeError" title="exceptions.TypeError"><code class="xref py py-exc docutils literal"><span class="pre">TypeError</span></code></a> です。例外型として出力される文字列は、発生した例外の組み込み名です。これは全ての組み込み例外について成り立ちますが、ユーザ定義の例外では (成り立つようにするのは有意義な慣習ですが) 必ずしも成り立ちません。標準例外の名前は組み込みの識別子です (予約語ではありません)。</p>
<p>残りの行は例外の詳細で、その例外の型と何が起きたかに依存します。</p>
<p>エラーメッセージの先頭部分では、例外が発生した実行コンテキスト (context) を、スタックのトレースバック (stack traceback) の形式で示しています。一般には、この部分にはソースコード行をリストしたトレースバックが表示されます。しかし、標準入力から読み取られたコードは表示されません。</p>
<p><a class="reference internal" href="../library/exceptions.html#bltin-exceptions"><span class="std std-ref">組み込み例外</span></a> には、組み込み例外とその意味がリストされています。</p>
</div>
<div class="section" id="handling-exceptions">
<span id="tut-handling"></span><h2>8.3. 例外を処理する<a class="headerlink" href="#handling-exceptions" title="このヘッドラインへのパーマリンク">¶</a></h2>
<p>例外を選別して処理するようなプログラムを書くことができます。以下の例を見てください。この例では、有効な文字列が入力されるまでユーザに入力を促しますが、ユーザがプログラムに (<code class="kbd docutils literal"><span class="pre">Control-C</span></code> か、またはオペレーティングシステムがサポートしている何らかのキーを使って) 割り込みをかけてプログラムを中断させることができるようにしています。ユーザが生成した割り込みは、 <a class="reference internal" href="../library/exceptions.html#exceptions.KeyboardInterrupt" title="exceptions.KeyboardInterrupt"><code class="xref py py-exc docutils literal"><span class="pre">KeyboardInterrupt</span></code></a> 例外が送出されることで通知されるということに注意してください。</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
<span class="gp">... </span> <span class="k">try</span><span class="p">:</span>
<span class="gp">... </span> <span class="n">x</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">raw_input</span><span class="p">(</span><span class="s2">"Please enter a number: "</span><span class="p">))</span>
<span class="gp">... </span> <span class="k">break</span>
<span class="gp">... </span> <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
<span class="gp">... </span> <span class="nb">print</span> <span class="s2">"Oops! That was no valid number. Try again..."</span>
<span class="gp">...</span>
</pre></div>
</div>
<p><a class="reference internal" href="../reference/compound_stmts.html#try"><code class="xref std std-keyword docutils literal"><span class="pre">try</span></code></a> 文は下記のように動作します。</p>
<ul class="simple">
<li>まず、 <em>try 節 (try clause)</em> (キーワード <a class="reference internal" href="../reference/compound_stmts.html#try"><code class="xref std std-keyword docutils literal"><span class="pre">try</span></code></a> と <a class="reference internal" href="../reference/compound_stmts.html#except"><code class="xref std std-keyword docutils literal"><span class="pre">except</span></code></a> の間の文) が実行されます。</li>
<li>何も例外が発生しなければ、 <em>except 節</em> をスキップして <a class="reference internal" href="../reference/compound_stmts.html#try"><code class="xref std std-keyword docutils literal"><span class="pre">try</span></code></a> 文の実行を終えます。</li>
<li>try 節内の実行中に例外が発生すると、その節の残りは飛ばされます。次に、例外型が <a class="reference internal" href="../reference/compound_stmts.html#except"><code class="xref std std-keyword docutils literal"><span class="pre">except</span></code></a> キーワードの後に指定されている例外に一致する場合、except 節が実行された後、 <a class="reference internal" href="../reference/compound_stmts.html#try"><code class="xref std std-keyword docutils literal"><span class="pre">try</span></code></a> 文の後ろへ実行が継続されます。</li>
<li>もしも except 節で指定された例外と一致しない例外が発生すると、その例外は <a class="reference internal" href="../reference/compound_stmts.html#try"><code class="xref std std-keyword docutils literal"><span class="pre">try</span></code></a> 文の外側に渡されます。例外に対するハンドラ (handler、処理部) がどこにもなければ、 <em>処理されない例外 (unhandled exception)</em> となり、上記に示したようなメッセージを出して実行を停止します。</li>
</ul>
<p>一つの <a class="reference internal" href="../reference/compound_stmts.html#try"><code class="xref std std-keyword docutils literal"><span class="pre">try</span></code></a> 文に複数の except 節を設けて、さまざまな例外に対するハンドラを指定することができます。同時に一つ以上のハンドラが実行されることはありません。ハンドラは対応する try 節内で発生した例外だけを処理し、同じ <a class="reference internal" href="../reference/compound_stmts.html#try"><code class="xref std std-keyword docutils literal"><span class="pre">try</span></code></a> 文内の別の例外ハンドラで起きた例外は処理しません。 except 節には複数の例外を丸括弧で囲ったタプルにして渡すことができます。例えば以下のようにします:</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="o">...</span> <span class="k">except</span> <span class="p">(</span><span class="ne">RuntimeError</span><span class="p">,</span> <span class="ne">TypeError</span><span class="p">,</span> <span class="ne">NameError</span><span class="p">):</span>
<span class="o">...</span> <span class="k">pass</span>
</pre></div>
</div>
<p>このタプルの周囲の括弧は必要です。というのも、 <code class="docutils literal"><span class="pre">except</span> <span class="pre">ValueError,</span> <span class="pre">e:</span></code> はモダンな Python で普通 <code class="docutils literal"><span class="pre">except</span> <span class="pre">ValueError</span> <span class="pre">as</span> <span class="pre">e:</span></code> と書く(後述)のと同じ意味のかつての文法でした。この古い文法は後方互換のために今でも残されています。つまり <code class="docutils literal"><span class="pre">except</span> <span class="pre">RuntimeError,</span> <span class="pre">TypeError</span></code> は <code class="docutils literal"><span class="pre">except</span> <span class="pre">(RuntimeError,</span> <span class="pre">TypeError):</span></code> と同じではなく、お望みのものとは違う <code class="docutils literal"><span class="pre">except</span> <span class="pre">RuntimeError</span> <span class="pre">as</span> <span class="pre">TypeError:</span></code> だということです。</p>
<p>最後の except 節では例外名を省いて、ワイルドカード (wildcard、総称記号) にすることができます。ワイルドカードの except 節は非常に注意して使ってください。というのは、ワイルドカードは通常のプログラムエラーをたやすく隠してしまうからです!ワイルドカードの except 節はエラーメッセージを出力した後に例外を再送出する (関数やメソッドの呼び出し側が同様にして例外を処理できるようにする) 用途にも使えます:</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">sys</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">f</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="s1">'myfile.txt'</span><span class="p">)</span>
<span class="n">s</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">readline</span><span class="p">()</span>
<span class="n">i</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">s</span><span class="o">.</span><span class="n">strip</span><span class="p">())</span>
<span class="k">except</span> <span class="ne">IOError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="nb">print</span> <span class="s2">"I/O error(</span><span class="si">{0}</span><span class="s2">): </span><span class="si">{1}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">e</span><span class="o">.</span><span class="n">errno</span><span class="p">,</span> <span class="n">e</span><span class="o">.</span><span class="n">strerror</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
<span class="nb">print</span> <span class="s2">"Could not convert data to an integer."</span>
<span class="k">except</span><span class="p">:</span>
<span class="nb">print</span> <span class="s2">"Unexpected error:"</span><span class="p">,</span> <span class="n">sys</span><span class="o">.</span><span class="n">exc_info</span><span class="p">()[</span><span class="mi">0</span><span class="p">]</span>
<span class="k">raise</span>
</pre></div>
</div>
<p><a class="reference internal" href="../reference/compound_stmts.html#try"><code class="xref std std-keyword docutils literal"><span class="pre">try</span></code></a> … <a class="reference internal" href="../reference/compound_stmts.html#except"><code class="xref std std-keyword docutils literal"><span class="pre">except</span></code></a> 文には、オプションで <em>else 節 (else clause)</em> を設けることができます。 <a class="reference internal" href="../reference/compound_stmts.html#else"><code class="xref std std-keyword docutils literal"><span class="pre">else</span></code></a> 節を設ける場合、全ての <a class="reference internal" href="../reference/compound_stmts.html#except"><code class="xref std std-keyword docutils literal"><span class="pre">except</span></code></a> 節よりも後ろに置かなければなりません。 <a class="reference internal" href="../reference/compound_stmts.html#else"><code class="xref std std-keyword docutils literal"><span class="pre">else</span></code></a> 節は try 節で全く例外が送出されなかったときに実行されるコードを書くのに役立ちます。例えば次のようにします:</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">:]:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">f</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">arg</span><span class="p">,</span> <span class="s1">'r'</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">IOError</span><span class="p">:</span>
<span class="nb">print</span> <span class="s1">'cannot open'</span><span class="p">,</span> <span class="n">arg</span>
<span class="k">else</span><span class="p">:</span>
<span class="nb">print</span> <span class="n">arg</span><span class="p">,</span> <span class="s1">'has'</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">f</span><span class="o">.</span><span class="n">readlines</span><span class="p">()),</span> <span class="s1">'lines'</span>
<span class="n">f</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</pre></div>
</div>
<p>追加のコードを追加するのは <a class="reference internal" href="../reference/compound_stmts.html#try"><code class="xref std std-keyword docutils literal"><span class="pre">try</span></code></a> 節の後ろよりも <a class="reference internal" href="../reference/compound_stmts.html#else"><code class="xref std std-keyword docutils literal"><span class="pre">else</span></code></a> 節の方がよいでしょう。なぜなら、そうすることで <a class="reference internal" href="../reference/compound_stmts.html#try"><code class="xref std std-keyword docutils literal"><span class="pre">try</span></code></a> … <a class="reference internal" href="../reference/compound_stmts.html#except"><code class="xref std std-keyword docutils literal"><span class="pre">except</span></code></a> 文で保護したいコードから送出されたもの以外の例外を偶然に捕捉してしまうという事態を避けられるからです。</p>
<p>例外が発生するとき、例外は関連付けられた値を持つことができます。この値は例外の <em>引数 (argument)</em> とも呼ばれます。引数の有無および引数の型は、例外の型に依存します。</p>
<p>except 節では、例外名 (または例外名タプル) の後に変数を指定することができます。この変数は例外インスタンスに結び付けられており、 <code class="docutils literal"><span class="pre">instance.args</span></code> に例外インスタンス生成時の引数が入っています。例外インスタンスには <a class="reference internal" href="../reference/datamodel.html#object.__str__" title="object.__str__"><code class="xref py py-meth docutils literal"><span class="pre">__str__()</span></code></a> が定義されており、 <code class="docutils literal"><span class="pre">.args</span></code> を参照しなくても引数を直接印字できるように利便性が図られています。</p>
<p>必要なら、例外を送出する前にインスタンス化して、任意の属性を追加できます。</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="k">try</span><span class="p">:</span>
<span class="gp">... </span> <span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s1">'spam'</span><span class="p">,</span> <span class="s1">'eggs'</span><span class="p">)</span>
<span class="gp">... </span><span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">inst</span><span class="p">:</span>
<span class="gp">... </span> <span class="nb">print</span> <span class="nb">type</span><span class="p">(</span><span class="n">inst</span><span class="p">)</span> <span class="c1"># the exception instance</span>
<span class="gp">... </span> <span class="nb">print</span> <span class="n">inst</span><span class="o">.</span><span class="n">args</span> <span class="c1"># arguments stored in .args</span>
<span class="gp">... </span> <span class="nb">print</span> <span class="n">inst</span> <span class="c1"># __str__ allows args to be printed directly</span>
<span class="gp">... </span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="n">inst</span><span class="o">.</span><span class="n">args</span>
<span class="gp">... </span> <span class="nb">print</span> <span class="s1">'x ='</span><span class="p">,</span> <span class="n">x</span>
<span class="gp">... </span> <span class="nb">print</span> <span class="s1">'y ='</span><span class="p">,</span> <span class="n">y</span>
<span class="gp">...</span>
<span class="go"><type 'exceptions.Exception'></span>
<span class="go">('spam', 'eggs')</span>
<span class="go">('spam', 'eggs')</span>
<span class="go">x = spam</span>
<span class="go">y = eggs</span>
</pre></div>
</div>
<p>例外が引数を持っていれば、それらは処理されない例外のメッセージの最後の部分 (「詳細説明」) に出力されます。</p>
<p>例外ハンドラは、try 節の直接内側で発生した例外を処理するだけではなく、その try 節から (たとえ間接的にでも) 呼び出された関数の内部で発生した例外も処理します。例えば:</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="k">def</span> <span class="nf">this_fails</span><span class="p">():</span>
<span class="gp">... </span> <span class="n">x</span> <span class="o">=</span> <span class="mi">1</span><span class="o">/</span><span class="mi">0</span>
<span class="gp">...</span>
<span class="gp">>>> </span><span class="k">try</span><span class="p">:</span>
<span class="gp">... </span> <span class="n">this_fails</span><span class="p">()</span>
<span class="gp">... </span><span class="k">except</span> <span class="ne">ZeroDivisionError</span> <span class="k">as</span> <span class="n">detail</span><span class="p">:</span>
<span class="gp">... </span> <span class="nb">print</span> <span class="s1">'Handling run-time error:'</span><span class="p">,</span> <span class="n">detail</span>
<span class="gp">...</span>
<span class="go">Handling run-time error: integer division or modulo by zero</span>
</pre></div>
</div>
</div>
<div class="section" id="raising-exceptions">
<span id="tut-raising"></span><h2>8.4. 例外を送出する<a class="headerlink" href="#raising-exceptions" title="このヘッドラインへのパーマリンク">¶</a></h2>
<p><a class="reference internal" href="../reference/simple_stmts.html#raise"><code class="xref std std-keyword docutils literal"><span class="pre">raise</span></code></a> 文を使って、特定の例外を発生させることができます。例えば:</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="k">raise</span> <span class="ne">NameError</span><span class="p">(</span><span class="s1">'HiThere'</span><span class="p">)</span>
<span class="gt">Traceback (most recent call last):</span>
File <span class="nb">"<stdin>"</span>, line <span class="m">1</span>, in <span class="n"><module></span>
<span class="gr">NameError</span>: <span class="n">HiThere</span>
</pre></div>
</div>
<p><a class="reference internal" href="../reference/simple_stmts.html#raise"><code class="xref std std-keyword docutils literal"><span class="pre">raise</span></code></a> は送出したい例外を引数として取ります。これは例外クラス(<code class="xref py py-class docutils literal"><span class="pre">Exception</span></code> を継承したクラス)か、例外クラスのインスタンスです。</p>
<p>例外が発生したかどうかを判定したいだけで、その例外を処理するつもりがなければ、単純な形式の <a class="reference internal" href="../reference/simple_stmts.html#raise"><code class="xref std std-keyword docutils literal"><span class="pre">raise</span></code></a> 文を使って例外を再送出させることができます:</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="k">try</span><span class="p">:</span>
<span class="gp">... </span> <span class="k">raise</span> <span class="ne">NameError</span><span class="p">(</span><span class="s1">'HiThere'</span><span class="p">)</span>
<span class="gp">... </span><span class="k">except</span> <span class="ne">NameError</span><span class="p">:</span>
<span class="gp">... </span> <span class="nb">print</span> <span class="s1">'An exception flew by!'</span>
<span class="gp">... </span> <span class="k">raise</span>
<span class="gp">...</span>
<span class="go">An exception flew by!</span>
<span class="gt">Traceback (most recent call last):</span>
File <span class="nb">"<stdin>"</span>, line <span class="m">2</span>, in <span class="n"><module></span>
<span class="gr">NameError</span>: <span class="n">HiThere</span>
</pre></div>
</div>
</div>
<div class="section" id="user-defined-exceptions">
<span id="tut-userexceptions"></span><h2>8.5. ユーザー定義例外<a class="headerlink" href="#user-defined-exceptions" title="このヘッドラインへのパーマリンク">¶</a></h2>
<p>プログラム上で新しい例外クラスを作成することで、独自の例外を指定することができます (Python のクラスについては <a class="reference internal" href="classes.html#tut-classes"><span class="std std-ref">クラス</span></a> 参照)。例外は、典型的に <a class="reference internal" href="../library/exceptions.html#exceptions.Exception" title="exceptions.Exception"><code class="xref py py-exc docutils literal"><span class="pre">Exception</span></code></a> クラスから、直接または間接的に派生したものです。例を示します:</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="k">class</span> <span class="nc">MyError</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
<span class="gp">... </span> <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
<span class="gp">... </span> <span class="bp">self</span><span class="o">.</span><span class="n">value</span> <span class="o">=</span> <span class="n">value</span>
<span class="gp">... </span> <span class="k">def</span> <span class="nf">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="gp">... </span> <span class="k">return</span> <span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">value</span><span class="p">)</span>
<span class="gp">...</span>
<span class="gp">>>> </span><span class="k">try</span><span class="p">:</span>
<span class="gp">... </span> <span class="k">raise</span> <span class="n">MyError</span><span class="p">(</span><span class="mi">2</span><span class="o">*</span><span class="mi">2</span><span class="p">)</span>
<span class="gp">... </span><span class="k">except</span> <span class="n">MyError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="gp">... </span> <span class="nb">print</span> <span class="s1">'My exception occurred, value:'</span><span class="p">,</span> <span class="n">e</span><span class="o">.</span><span class="n">value</span>
<span class="gp">...</span>
<span class="go">My exception occurred, value: 4</span>
<span class="gp">>>> </span><span class="k">raise</span> <span class="n">MyError</span><span class="p">(</span><span class="s1">'oops!'</span><span class="p">)</span>
<span class="gt">Traceback (most recent call last):</span>
File <span class="nb">"<stdin>"</span>, line <span class="m">1</span>, in <span class="n"><module></span>
<span class="gr">__main__.MyError</span>: <span class="n">'oops!'</span>
</pre></div>
</div>
<p>この例では <code class="xref py py-class docutils literal"><span class="pre">Exception</span></code> のデフォルト <a class="reference internal" href="../reference/datamodel.html#object.__init__" title="object.__init__"><code class="xref py py-meth docutils literal"><span class="pre">__init__()</span></code></a> がオーバーライドされています。新しい振る舞いでは、単に <em>value</em> 属性を作ります。これは、デフォルトの <em>args</em> 属性を作成する振る舞いを置き換えています。</p>
<p>例外クラスでは、普通のクラスができることなら何でも定義することができますが、通常は単純なものにしておきます。大抵は、いくつかの属性だけを提供し、例外が発生したときにハンドラがエラーに関する情報を取り出せるようにする程度にとどめます。複数の別個の例外を送出するようなモジュールを作成する際には、そのモジュールで定義されている例外の基底クラスを作成するのが一般的なプラクティスです:</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">Error</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
<span class="sd">"""Base class for exceptions in this module."""</span>
<span class="k">pass</span>
<span class="k">class</span> <span class="nc">InputError</span><span class="p">(</span><span class="n">Error</span><span class="p">):</span>
<span class="sd">"""Exception raised for errors in the input.</span>
<span class="sd"> Attributes:</span>
<span class="sd"> expr -- input expression in which the error occurred</span>
<span class="sd"> msg -- explanation of the error</span>
<span class="sd"> """</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">expr</span><span class="p">,</span> <span class="n">msg</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">expr</span> <span class="o">=</span> <span class="n">expr</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span> <span class="o">=</span> <span class="n">msg</span>
<span class="k">class</span> <span class="nc">TransitionError</span><span class="p">(</span><span class="n">Error</span><span class="p">):</span>
<span class="sd">"""Raised when an operation attempts a state transition that's not</span>
<span class="sd"> allowed.</span>
<span class="sd"> Attributes:</span>
<span class="sd"> prev -- state at beginning of transition</span>
<span class="sd"> next -- attempted new state</span>
<span class="sd"> msg -- explanation of why the specific transition is not allowed</span>
<span class="sd"> """</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">prev</span><span class="p">,</span> <span class="nb">next</span><span class="p">,</span> <span class="n">msg</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">prev</span> <span class="o">=</span> <span class="n">prev</span>
<span class="bp">self</span><span class="o">.</span><span class="n">next</span> <span class="o">=</span> <span class="nb">next</span>
<span class="bp">self</span><span class="o">.</span><span class="n">msg</span> <span class="o">=</span> <span class="n">msg</span>
</pre></div>
</div>
<p>ほとんどの例外は、標準の例外の名前付けと同様に、 "Error" で終わる名前で定義されています。</p>
<p>多くの標準モジュールでは、モジュールで定義されている関数内で発生する可能性のあるエラーを報告させるために、独自の例外を定義しています。クラスについての詳細な情報は <a class="reference internal" href="classes.html#tut-classes"><span class="std std-ref">クラス</span></a> 章で提供されています。</p>
</div>
<div class="section" id="defining-clean-up-actions">
<span id="tut-cleanup"></span><h2>8.6. クリーンアップ動作を定義する<a class="headerlink" href="#defining-clean-up-actions" title="このヘッドラインへのパーマリンク">¶</a></h2>
<p><a class="reference internal" href="../reference/compound_stmts.html#try"><code class="xref std std-keyword docutils literal"><span class="pre">try</span></code></a> 文にはもう一つオプションの節があります。この節はクリーンアップ動作を定義するためのもので、どんな状況でも必ず実行されます。例を示します:</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="k">try</span><span class="p">:</span>
<span class="gp">... </span> <span class="k">raise</span> <span class="ne">KeyboardInterrupt</span>
<span class="gp">... </span><span class="k">finally</span><span class="p">:</span>
<span class="gp">... </span> <span class="nb">print</span> <span class="s1">'Goodbye, world!'</span>
<span class="gp">...</span>
<span class="go">Goodbye, world!</span>
<span class="nc">KeyboardInterrupt</span>
<span class="gt">Traceback (most recent call last):</span>
File <span class="nb">"<stdin>"</span>, line <span class="m">2</span>, in <span class="n"><module></span>
</pre></div>
</div>
<p><em>finally 節 (finally clause)</em> は、例外が発生したかどうかに関わらず、 <a class="reference internal" href="../reference/compound_stmts.html#try"><code class="xref std std-keyword docutils literal"><span class="pre">try</span></code></a> 文を抜ける前に常に実行されます。 <a class="reference internal" href="../reference/compound_stmts.html#try"><code class="xref std std-keyword docutils literal"><span class="pre">try</span></code></a> 節の中で例外が発生して、 <a class="reference internal" href="../reference/compound_stmts.html#except"><code class="xref std std-keyword docutils literal"><span class="pre">except</span></code></a> 節で処理されていない場合、または <a class="reference internal" href="../reference/compound_stmts.html#except"><code class="xref std std-keyword docutils literal"><span class="pre">except</span></code></a> 節か <a class="reference internal" href="../reference/compound_stmts.html#else"><code class="xref std std-keyword docutils literal"><span class="pre">else</span></code></a> 節で例外が発生した場合は、 <a class="reference internal" href="../reference/compound_stmts.html#finally"><code class="xref std std-keyword docutils literal"><span class="pre">finally</span></code></a> 節を実行した後、その例外を再送出します。 <a class="reference internal" href="../reference/compound_stmts.html#finally"><code class="xref std std-keyword docutils literal"><span class="pre">finally</span></code></a> 節はまた、 <a class="reference internal" href="../reference/compound_stmts.html#try"><code class="xref std std-keyword docutils literal"><span class="pre">try</span></code></a> 節から <a class="reference internal" href="../reference/simple_stmts.html#break"><code class="xref std std-keyword docutils literal"><span class="pre">break</span></code></a> 文や <a class="reference internal" href="../reference/simple_stmts.html#continue"><code class="xref std std-keyword docutils literal"><span class="pre">continue</span></code></a> 文、 <a class="reference internal" href="../reference/simple_stmts.html#return"><code class="xref std std-keyword docutils literal"><span class="pre">return</span></code></a> 文経由で抜ける際にも、 "抜ける途中で" 実行されます。より複雑な例です (<a class="reference internal" href="../reference/compound_stmts.html#except"><code class="xref std std-keyword docutils literal"><span class="pre">except</span></code></a> 節や <a class="reference internal" href="../reference/compound_stmts.html#finally"><code class="xref std std-keyword docutils literal"><span class="pre">finally</span></code></a> 節が同じ <a class="reference internal" href="../reference/compound_stmts.html#try"><code class="xref std std-keyword docutils literal"><span class="pre">try</span></code></a> 文の中にあって、 Python 2.5 以降で動作します)。</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="k">def</span> <span class="nf">divide</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">):</span>
<span class="gp">... </span> <span class="k">try</span><span class="p">:</span>
<span class="gp">... </span> <span class="n">result</span> <span class="o">=</span> <span class="n">x</span> <span class="o">/</span> <span class="n">y</span>
<span class="gp">... </span> <span class="k">except</span> <span class="ne">ZeroDivisionError</span><span class="p">:</span>
<span class="gp">... </span> <span class="nb">print</span> <span class="s2">"division by zero!"</span>
<span class="gp">... </span> <span class="k">else</span><span class="p">:</span>
<span class="gp">... </span> <span class="nb">print</span> <span class="s2">"result is"</span><span class="p">,</span> <span class="n">result</span>
<span class="gp">... </span> <span class="k">finally</span><span class="p">:</span>
<span class="gp">... </span> <span class="nb">print</span> <span class="s2">"executing finally clause"</span>
<span class="gp">...</span>
<span class="gp">>>> </span><span class="n">divide</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="go">result is 2</span>
<span class="go">executing finally clause</span>
<span class="gp">>>> </span><span class="n">divide</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
<span class="go">division by zero!</span>
<span class="go">executing finally clause</span>
<span class="gp">>>> </span><span class="n">divide</span><span class="p">(</span><span class="s2">"2"</span><span class="p">,</span> <span class="s2">"1"</span><span class="p">)</span>
<span class="go">executing finally clause</span>
<span class="gt">Traceback (most recent call last):</span>
File <span class="nb">"<stdin>"</span>, line <span class="m">1</span>, in <span class="n"><module></span>
File <span class="nb">"<stdin>"</span>, line <span class="m">3</span>, in <span class="n">divide</span>
<span class="gr">TypeError</span>: <span class="n">unsupported operand type(s) for /: 'str' and 'str'</span>
</pre></div>
</div>
<p>見てわかるとおり、 <a class="reference internal" href="../reference/compound_stmts.html#finally"><code class="xref std std-keyword docutils literal"><span class="pre">finally</span></code></a> 節はどの場合にも実行されています。文字列を割り算することで発生した <a class="reference internal" href="../library/exceptions.html#exceptions.TypeError" title="exceptions.TypeError"><code class="xref py py-exc docutils literal"><span class="pre">TypeError</span></code></a> は <a class="reference internal" href="../reference/compound_stmts.html#except"><code class="xref std std-keyword docutils literal"><span class="pre">except</span></code></a> 節で処理されていないので、 <a class="reference internal" href="../reference/compound_stmts.html#finally"><code class="xref std std-keyword docutils literal"><span class="pre">finally</span></code></a> 節実行後に再度送出されています。</p>
<p>実世界のアプリケーションでは、 <a class="reference internal" href="../reference/compound_stmts.html#finally"><code class="xref std std-keyword docutils literal"><span class="pre">finally</span></code></a> 節は(ファイルやネットワーク接続などの)外部リソースを、利用が成功したかどうかにかかわらず解放するために便利です。</p>
</div>
<div class="section" id="predefined-clean-up-actions">
<span id="tut-cleanup-with"></span><h2>8.7. 定義済みクリーンアップ処理<a class="headerlink" href="#predefined-clean-up-actions" title="このヘッドラインへのパーマリンク">¶</a></h2>
<p>オブジェクトのなかには、その利用の成否にかかわらず、不要になった際に実行される標準的なクリーンアップ処理が定義されているものがあります。以下の、ファイルをオープンして内容を画面に表示する例をみてください。</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="nb">open</span><span class="p">(</span><span class="s2">"myfile.txt"</span><span class="p">):</span>
<span class="nb">print</span> <span class="n">line</span><span class="p">,</span>
</pre></div>
</div>
<p>このコードの問題点は、コードの実行が終わった後に不定の時間ファイルを開いたままでいることです。これは単純なスクリプトでは問題になりませんが、大きなアプリケーションでは問題になりえます。 <a class="reference internal" href="../reference/compound_stmts.html#with"><code class="xref std std-keyword docutils literal"><span class="pre">with</span></code></a> 文はファイルのようなオブジェクトが常に、即座に正しくクリーンアップされることを保証します。</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s2">"myfile.txt"</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">f</span><span class="p">:</span>
<span class="nb">print</span> <span class="n">line</span><span class="p">,</span>
</pre></div>
</div>
<p>この文が実行されたあとで、たとえ行の処理中に問題があったとしても、ファイル <em>f</em> は常に close されます。ファイルなどの、定義済みクリーンアップ処理を持つオブジェクトについては、それぞれのドキュメントで示されます。</p>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h3><a href="../contents.html">目次</a></h3>
<ul>
<li><a class="reference internal" href="#">8. エラーと例外</a><ul>
<li><a class="reference internal" href="#syntax-errors">8.1. 構文エラー</a></li>
<li><a class="reference internal" href="#exceptions">8.2. 例外</a></li>
<li><a class="reference internal" href="#handling-exceptions">8.3. 例外を処理する</a></li>
<li><a class="reference internal" href="#raising-exceptions">8.4. 例外を送出する</a></li>
<li><a class="reference internal" href="#user-defined-exceptions">8.5. ユーザー定義例外</a></li>
<li><a class="reference internal" href="#defining-clean-up-actions">8.6. クリーンアップ動作を定義する</a></li>
<li><a class="reference internal" href="#predefined-clean-up-actions">8.7. 定義済みクリーンアップ処理</a></li>
</ul>
</li>
</ul>
<h4>前のトピックへ</h4>
<p class="topless"><a href="inputoutput.html"
title="前の章へ">7. 入力と出力</a></p>
<h4>次のトピックへ</h4>
<p class="topless"><a href="classes.html"
title="次の章へ">9. クラス</a></p>
<h3>このページ</h3>
<ul class="this-page-menu">
<li><a href="../bugs.html">バグ報告</a></li>
<li><a href="https://github.com/python/cpython/blob/2.7/Doc/tutorial/errors.rst"
rel="nofollow">ソースの表示</a>
</li>
</ul>
<div id="searchbox" style="display: none" role="search">
<h3>クイック検索</h3>
<form class="search" action="../search.html" method="get">
<div><input type="text" name="q" /></div>
<div><input type="submit" value="検索" /></div>
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>ナビゲーション</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="総索引"
>索引</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Pythonモジュール索引"
>モジュール</a> |</li>
<li class="right" >
<a href="classes.html" title="9. クラス"
>次へ</a> |</li>
<li class="right" >
<a href="inputoutput.html" title="7. 入力と出力"
>前へ</a> |</li>
<li><img src="../_static/py.png" alt=""
style="vertical-align: middle; margin-top: -1px"/></li>
<li><a href="http://www.python.jp/">Python</a> »</li>
<li>
<span class="version_switcher_placeholder">2.7.14</span>
<a href="../index.html">ドキュメント</a> »
</li>
<li class="nav-item nav-item-1"><a href="index.html" >Python チュートリアル</a> »</li>
</ul>
</div>
<div class="footer">
© <a href="../copyright.html">Copyright</a> 1990-2018, Python Software Foundation (translated by Python ドキュメント日本語翻訳プロジェクト).
<br />
Python Software Foundation は非営利団体です。
<a href="https://www.python.org/psf/donations/">寄付</a>
<br />
最終更新日時: 2018-07-29
<a href="../bugs.html">バグを見つけたら</a>?
<br />
このドキュメントは <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.6.5 を使って作成されました。
</div>
</body>
</html>