回答編集履歴
2
コードを追加
answer
CHANGED
@@ -1,2 +1,40 @@
|
|
1
1
|
withステートメントは`__enter__`関数と`__exit__`関数のラッパーになっていますが、この内`__enter__`関数内でエラーが発生した場合に`__exit__`関数は呼ばれません(python3.6.3で確認)。
|
2
|
-
この場合は安全のために、withを使わずに明示的にオープン・クローズをした方がいいかと思います。
|
2
|
+
この場合は安全のために、withを使わずに明示的にオープン・クローズをした方がいいかと思います。
|
3
|
+
修正例としてはこのようなコードになります。
|
4
|
+
```python
|
5
|
+
import urllib.request
|
6
|
+
|
7
|
+
def check_status(url):
|
8
|
+
try:
|
9
|
+
response = urllib.request.urlopen(url, timeout=10)
|
10
|
+
return response.code
|
11
|
+
except urllib.error.HTTPError as e:
|
12
|
+
return e.code
|
13
|
+
except Exception as e:
|
14
|
+
print(str(e))
|
15
|
+
return -1
|
16
|
+
finally:
|
17
|
+
response.close()
|
18
|
+
|
19
|
+
status = check_status('https://www.hoge.com/')
|
20
|
+
print("access status:", status)
|
21
|
+
if status != 200:
|
22
|
+
print("access error.")
|
23
|
+
# 疎通失敗時のアクション
|
24
|
+
```
|
25
|
+
`urlopen`関数の怖いところは、標準の`open`や`socket.socket.connect`などと違って名前解決が出来なかった、そもそもソケットが作れなかった等の場合を除きエラーが発生するときには既に接続が確立していることです。
|
26
|
+
もし、標準以外のライブラリを使うことに抵抗が無いなら`urllib`ではなく`requests`等の高水準ライブラリを使うとよいと思います。
|
27
|
+
一応サンプルコードもおいときますね。
|
28
|
+
```python
|
29
|
+
from requests import get
|
30
|
+
|
31
|
+
def check_status(url):
|
32
|
+
#hostが見つからない場合、404が返ります
|
33
|
+
return get(url, timeout=10).status_code
|
34
|
+
|
35
|
+
status = check_status('https://www.hoge.com/')
|
36
|
+
print("access status:", status)
|
37
|
+
if status != 200:
|
38
|
+
print("access error.")
|
39
|
+
# 疎通失敗時のアクション
|
40
|
+
```
|
1
情報を追加
answer
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
withステートメントは`__enter__`関数と`__exit__`関数のラッパーになっていますが、この内`__enter__`関数内でエラーが発生した場合に`__exit__`関数は呼ばれません。
|
1
|
+
withステートメントは`__enter__`関数と`__exit__`関数のラッパーになっていますが、この内`__enter__`関数内でエラーが発生した場合に`__exit__`関数は呼ばれません(python3.6.3で確認)。
|
2
2
|
この場合は安全のために、withを使わずに明示的にオープン・クローズをした方がいいかと思います。
|