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