質問編集履歴

2

誤字修正

2020/10/17 05:32

投稿

bg_t
bg_t

スコア1

test CHANGED
File without changes
test CHANGED
@@ -1,11 +1,15 @@
1
1
  win10 VS2019でpython3.7(64bit)を利用してプログラムを書いているのですが、プログラム内で with を使用するとプログラム終了時にコンソールにエラーが表示されます
2
2
 
3
+ ```python
4
+
3
5
  # ココ
4
6
 
5
7
  f = open()
6
8
 
7
9
  f.close()
8
10
 
11
+ ```
12
+
9
13
  形式にするとエラーが表示されなくなるのですが、これ以上の原因が究明できないので教えて頂けると嬉しいです
10
14
 
11
15
 

1

エラーが再現できるコードを追加しました

2020/10/17 05:32

投稿

bg_t
bg_t

スコア1

test CHANGED
File without changes
test CHANGED
@@ -1,45 +1,433 @@
1
- win10 VS2019でpython3.7(64bit)を利用してプログラムを書いているのですが、プログラム内で with を使用するとプログラム終了時にコンソールにエラーが表示されます
1
+ win10 VS2019でpython3.7(64bit)を利用してプログラムを書いているのですが、プログラム内で with を使用するとプログラム終了時にコンソールにエラーが表示されます
2
-
2
+
3
- a=0はエラー位置を特定するために一時的に書いたもので、本来なら書き込みを行っています
3
+ # ココ
4
-
4
+
5
- したのプログラムはプログラムを小さく再現したものになります(これで単体ではエラーは発生しません)
5
+ f = open()
6
+
6
-
7
+ f.close()
8
+
7
- プログラム全体を貼とが出来ので、これ情報で原因が推測できる方がらっしゃいましたら教えて頂けるといです
9
+ 形式にするとエラー表示されくなるのですが、これ以上の原因が究明できので教えて頂けると嬉しいです
8
-
9
- withの行はプログラム上では通過していないのに、コメントアウトすると警告が消えるので原因がわかりません
10
+
11
+
10
12
 
11
13
 
12
14
 
13
15
  ```python
14
16
 
15
- TEST = False
16
-
17
-
18
-
19
- if TEST:
20
-
21
- # エラーが表示される
22
-
23
- with open(PATH, mode="w") as f:
24
-
25
- a = 0
17
+ import os
18
+
19
+ import pandas as pd
20
+
21
+ from tqdm import tqdm
22
+
23
+ import re # 文字列編集
24
+
25
+ import time
26
+
27
+ import lib
28
+
29
+
30
+
31
+ try:
32
+
33
+ import google.colab
34
+
35
+ IN_COLAB = True
36
+
37
+ except:
38
+
39
+ IN_COLAB = False
40
+
41
+
42
+
43
+ if IN_COLAB: # Google Colabで実行している場合
44
+
45
+ CSV_PATH = "/content/rakuten_product_data.csv"
46
+
47
+ URL_LIST_PATH = "./image_url.lst"
48
+
49
+ IMAGE_URL_CSV_PATH = "./delete_image_name.csv"
50
+
51
+ R_CABINET_FORMAT_PATH = "./r_cabinet_delete_format.txt"
52
+
53
+ URL_INFO_TEXT_PATH = "./image_url.txt"
54
+
55
+ else: # ローカルで実行している場合
56
+
57
+ CSV_PATH = "./rakuten_product_data.csv"
58
+
59
+ URL_LIST_PATH = "./image_url.lst"
60
+
61
+ IMAGE_URL_CSV_PATH = "./delete_image_name.csv"
62
+
63
+ R_CABINET_FORMAT_PATH = "./r_cabinet_delete_format.txt"
64
+
65
+ URL_INFO_TEXT_PATH = "./image_url.txt"
66
+
67
+ VERSION = "1.0.0"
68
+
69
+ STOCK = 0 # 在庫あり
70
+
71
+ NO_STOCK = 1 # 在庫なし
72
+
73
+ LOCAL_IMG_DIR = "./image"
74
+
75
+ RAKUTEN_FORMAT_DELETE_PATH = "" # RMSフォーマット用に画像URLから削除する部分
76
+
77
+ IMAGE_URL_CSV_COLUMNS = ["file_name", "url", "deleted", "error"]
78
+
79
+
80
+
81
+
82
+
83
+
84
+
85
+ if os.path.isfile(CSV_PATH):
86
+
87
+ load_csv = pd.read_csv(CSV_PATH, encoding="cp932")
88
+
89
+ else:
90
+
91
+ exit()
92
+
93
+
94
+
95
+ stock_or = [load_csv[load_csv["在庫数"] == 1], load_csv[load_csv["在庫数"] == 0]] # 在庫がある商品とない商品のリスト
96
+
97
+ all_num = len(load_csv) # 商品の数
98
+
99
+ stock_num = len(stock_or[STOCK]) # 在庫あり商品の数
100
+
101
+
102
+
103
+ img_num_no_stock = 0 # 在庫がない商品に含まれる画像の数
104
+
105
+ img_num_stock = 0 # 在庫がある商品に含まれる画像の数
106
+
107
+ not_top_img_num = 0 # サムネを含まない、在庫がない商品に含まれる画像の数
108
+
109
+ no_img_item_num = 0 # 画像が無い商品の数
110
+
111
+ i = 0
112
+
113
+
114
+
115
+ for row_stock_or in stock_or:
116
+
117
+ for row in row_stock_or["商品画像URL"]:
118
+
119
+ if type(row) == str and len(row.split()) != 0: # URL情報が格納されていれば
120
+
121
+ if i == STOCK: # 在庫がある場合
122
+
123
+ img_num_stock += len(row.split())
124
+
125
+ else: # 在庫がない場合
126
+
127
+ img_num_no_stock += len(row.split())
128
+
129
+ not_top_img_num += len(row.split()) - 1
130
+
131
+ else:
132
+
133
+ no_img_item_num += 1
134
+
135
+ i += 1
136
+
137
+
138
+
139
+
140
+
141
+ #中略
142
+
143
+
144
+
145
+
146
+
147
+ item_numbers = list(stock_or[NO_STOCK]["商品管理番号(商品URL)"])
148
+
149
+ item_names = list(stock_or[NO_STOCK]["商品名"])
150
+
151
+ img_urls = list(stock_or[NO_STOCK]["商品画像URL"])
152
+
153
+ img_urls_stock = list(stock_or[STOCK]["商品画像URL"])
154
+
155
+
156
+
157
+ #中略
158
+
159
+
160
+
161
+
162
+
163
+ print("\n削除画像一覧をテキストに出力しますか? (y/n)")
164
+
165
+ in_str = input()
166
+
167
+ if in_str == "y":
168
+
169
+ output_data = [] # CSVとして出力するためのデータ
170
+
171
+ for i in range(len(img_urls)):
172
+
173
+ if type(img_urls[i]) == str: # URLが含まれない商品をスキップする
174
+
175
+ images = img_urls[i].split(" ") # 一つの商品に含まれるURLのリスト
176
+
177
+ for j in range(1, len(images)): # サムネの画像をスキップする
178
+
179
+ output_data.append([os.path.basename(images[j]), images[j], False])
180
+
181
+
182
+
183
+ image_name_list_stock = [] # 在庫がある商品の写真のリスト
184
+
185
+ for i in range(len(img_urls_stock)):
186
+
187
+ if type(img_urls_stock[i]) == str: # URLが含まれない商品をスキップする
188
+
189
+ images = img_urls_stock[i].split(" ") # 一つの商品に含まれるURLのリスト
190
+
191
+ for j in range(1, len(images)): # サムネの画像をスキップする
192
+
193
+ image_name_list_stock.append(os.path.basename(images[j]))
194
+
195
+
196
+
197
+ print("画像情報を精査します")
198
+
199
+ exclusion_image_list = [] # 削除する画像リストから取り除く画像
200
+
201
+ image_name_list = [row[0] for row in output_data] # 在庫がない商品の写真のリスト
202
+
203
+ for row in tqdm(image_name_list):
204
+
205
+ for row2 in image_name_list_stock:
206
+
207
+ if row == row2:
208
+
209
+ exclusion_image_list.append(row)
210
+
211
+ exclusion_image_list = set(exclusion_image_list) # 万が一同じ画像があれば取り除く
212
+
213
+ if len(exclusion_image_list) == 0:
214
+
215
+ print("\n問題は見つかりませんでした")
216
+
217
+ else:
218
+
219
+ print("\n" + str(len(exclusion_image_list)) + " 件の販売中商品への再利用画像が見つかりました")
220
+
221
+ print(exclusion_image_list)
222
+
223
+
224
+
225
+ for row in output_data:
226
+
227
+ row.append(False) # 4 列目を追加する
228
+
229
+ for row2 in exclusion_image_list:
230
+
231
+ if row[0] == row2:
232
+
233
+ row[3] = True # 4 列目を書き換える
234
+
235
+
236
+
237
+ list_len = len(image_name_list) # リストの大きさ
238
+
239
+ unique_list_len = len(set(image_name_list)) # 一意に変換したリストの大きさ
240
+
241
+ if list_len != unique_list_len:
242
+
243
+ print("\n警告 : 同名の画像が存在します " + str(list_len-unique_list_len) + " / " + str(unique_list_len))
244
+
245
+ print([x for x in dict.fromkeys(image_name_list) if image_name_list.count(x) > 1])
246
+
247
+ csv_df = pd.DataFrame(output_data, columns=IMAGE_URL_CSV_COLUMNS)
248
+
249
+ csv_df.to_csv(IMAGE_URL_CSV_PATH, index=False)
250
+
251
+ print("\n削除すべき画像の情報をCSV形式で出力しました")
252
+
253
+
254
+
255
+
256
+
257
+ if os.path.isfile(IMAGE_URL_CSV_PATH):
258
+
259
+ load_img_csv = pd.read_csv(IMAGE_URL_CSV_PATH, encoding="cp932")
260
+
261
+ else:
262
+
263
+ lib.print_error_log("削除画像一覧ファイルが見つかりませんでした")
264
+
265
+ exit()
266
+
267
+
268
+
269
+ with open(R_CABINET_FORMAT_PATH, mode="w") as f: # ココ
270
+
271
+ for i in range(len(load_img_csv[IMAGE_URL_CSV_COLUMNS[0]])):
272
+
273
+ if not load_img_csv["error"][i]:
274
+
275
+ f.write(load_img_csv["url"][i].replace(RAKUTEN_FORMAT_DELETE_PATH, "") + "\n") # 指定のフォーマットに変換して出力する
276
+
277
+
278
+
279
+
280
+
281
+ lib.program_pause()
282
+
283
+ ```
284
+
285
+ lib.py↓
286
+
287
+ ```python
288
+
289
+ import os
290
+
291
+ import time
292
+
293
+ import datetime
294
+
295
+ import urllib.error # urlを扱うモジュール
296
+
297
+ import urllib.request
298
+
299
+ import inspect # 活動中のオブジェクトの情報を取得する
300
+
301
+
302
+
303
+ __version__ = "1.0.0"
304
+
305
+
306
+
307
+ # ログを出力する
308
+
309
+ def print_log(message, console_print = True, error_frame = None):
310
+
311
+ LOG_PATH = "./lib.log"
312
+
313
+ if error_frame != None: # エラーログの場合はファイルを変更する
314
+
315
+ LOG_PATH = "./error.log"
316
+
317
+ if console_print:
318
+
319
+ print(message)
26
320
 
27
321
 
28
322
 
29
-
323
+ time_now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") # 現在時刻を取得する
324
+
30
-
325
+ if not os.path.isfile(LOG_PATH) or os.path.getsize(LOG_PATH) < 1024*1000*10: # 10MBより小さければ出力する
326
+
327
+ with open(LOG_PATH, mode="a") as f:
328
+
329
+ if error_frame != None: # エラーログ
330
+
331
+ f.write("[{}] {}({})".format(time_now, error_frame.f_code.co_name, error_frame.f_lineno).ljust(60) + message + "\n")
332
+
333
+ else: # 普通のログ
334
+
335
+ f.write("[{}] {}\n".format(time_now, message))
336
+
337
+ return True
338
+
339
+ else:
340
+
341
+ print("ログファイルの容量がいっぱいの為、出力を中止しました")
342
+
343
+ return False
344
+
345
+
346
+
31
- # エラーなし
347
+ # エラーログを出力する
348
+
32
-
349
+ def print_error_log(message, console_print = True):
350
+
351
+ frame = inspect.currentframe().f_back # 関数が呼ばれた場所の情報を取得する
352
+
353
+ return print_log(message, console_print, frame)
354
+
355
+
356
+
357
+ # インターネット上からファイルをダウンロードする関数
358
+
359
+ def download_file(url, dst_path):
360
+
361
+ try:
362
+
363
+ with urllib.request.urlopen(url) as web_file:
364
+
365
+ data = web_file.read()
366
+
367
+ with open(dst_path, mode='wb') as local_file:
368
+
369
+ local_file.write(data)
370
+
371
+ time.sleep(0.1)
372
+
373
+ return True
374
+
375
+ except urllib.error.URLError as e:
376
+
377
+ print_error_log(e)
378
+
379
+ return False
380
+
381
+
382
+
383
+ # ファイルをダウンロードして、失敗時に再ダウンロードを試みる関数
384
+
385
+ def download_and_check_file(url, dst_path):
386
+
387
+ TRIAL_NUM = 300 # 失敗時の試行回数
388
+
389
+ TRIAL_INTERVAL = 5 # 再ダウンロード時のクールタイム
390
+
391
+ download_file(url, dst_path)
392
+
393
+ for i in range(TRIAL_NUM):
394
+
395
+ if not os.path.isfile(dst_path):
396
+
397
+ print_error_log("ダウンロードに失敗しました、" + str(TRIAL_INTERVAL) + "秒後に再ダウンロードします ( " + str(i + 1) + " Fail )")
398
+
399
+ time.sleep(TRIAL_INTERVAL)
400
+
401
+ download_file(url, dst_path)
402
+
403
+ else: # ダウンロード成功
404
+
405
+ return True
406
+
407
+ return False
408
+
409
+
410
+
411
+ # プログラム終了時に一時停止する関数
412
+
413
+ def program_pause(program_end = True):
414
+
415
+ if not __debug__: # デバッグでなければ一時停止する
416
+
33
- f = open()
417
+ if program_end:
34
-
418
+
35
- a=0
419
+ message = "Press Enter key to exit . . ."
36
-
420
+
37
- f.close()
421
+ else:
422
+
423
+ message = "Press Enter key to continue . . ."
424
+
425
+ input(message)
426
+
427
+ return True
38
428
 
39
429
  ```
40
430
 
41
-
42
-
43
431
  Traceback (most recent call last):
44
432
 
45
433
  File "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python37_64\lib\runpy.py", line 193, in _run_module_as_main