pythonを使用してExcelファイルの操作を勉強しています。
本日の気づき(復習)は、ログの出力に関してです。
pythonでExcelを操作するため、openpyxlというパッケージを使用しています。
今まではとりあえずプログラムを記述することに注力してきました。
今後の事を考えると、ちゃんと処理が実行できているか確認するためにログを出力していきたいです。
loggingモジュール
標準ライブラリなので追加インストールは必要ありません。
https://docs.python.org/ja/3/library/logging.html
今回はこちらで入力した数だけブックを作り、一緒にログファイルも作る記述をしてみます。
ログファイルには処理の開始と終了、エラー発生時にログが出力されるようにしたいです。
logging.basicConfigメソッド
logging.basicConfig(filename=ログのファイル名, level=ログのレベル, format=ログの書式)
上記の記述でログのファイル名や書式を指定します。
format引数に指定す出来る書式は下のページをご確認ください。
ログ出力を行うメソッドはログのレベルごとに用意されています。
レベルは出力する内容(重要度)によって使い分けが出来るので
該当するレベルのログのみを抽出する事が出来ます。
- logging.debug()
- logging.info()
- logging.warning()
- logging.error()
- logging.critical()
下に行くほど重要度が高いです。
basicConfigメソッドのlevel引数に指定したレベルよりも低いものは
ログファイルには出力されません。
level=logging.WARNING
-->DEBUG,INFOレベルのログは出力されない
後、気を付けないといけない点は、Windouwsの場合
作成されたログファイルの文字コードはCP932になるということのようです。
Windouwsにもとからあるメモ帳を使えば大丈夫な様ですね。
import logging
import sys
from openpyxl import Workbook
logging.basicConfig(filename='create_book.log',
level=logging.INFO,
# ログの書式を、「日時」「レベル」「ログメッセージに設定」
format='%(asctime)s: [%(levelname)s] %(message)s')
logging.info('処理を開始しました')
try:
count = sys.argv[1]
for i in range(int(count)):
wb = Workbook()
ws = wb.active
ws.title = '概要'
file_name = f'資料_{i + 1}.xlsx'
wb.save(file_name)
logging.info('ブックを作成しました: %s', file_name)
# 例外が発生した場合スタックトレースを出力
except Exception:
logging.exception('例外が発生しました')
logging.info('処理が終了しました')
ここでも、見慣れない言葉が出てきました。
スタックトレース
スタックトレースは、プログラムで例外が発生した際に、
- どのように関数が呼び出されたのか
- どこでエラーが発生したのか
を特定できる情報です。
不具合発生時の原因究明に、重宝されます。
import traceback
def a():
b()
def b():
c()
def c():
char = None
char.format('hello')
try:
a()
except Exception as e:
print(traceback.format_exc())
こちらを実行すると
$ python3 sample.py
Traceback (most recent call last):
File "sample.py", line 14, in <module>
a()
File "ssample.py", line 5, in a
b()
File "ssample.py", line 8, in b
c()
File "ssample.py", line 12, in c
char.format('hello')
AttributeError: 'NoneType' object has no attribute 'format'
英語がたくさん表示される為か見ているだけで気がめいりますが、よ~く読むと
sample.pyの12行目(line 12)で、c()関数(in c)にある、char.format('hello')
でエラーが発生し、
エラー内容は'NoneType' object has no attribute 'format'
ということがわかります。
こんな感じで、どうやってエラーになったかがわかると修正もしやすいですね。
今回は個人的にちょっとレベルが高かったように感じます。
Railsの時もそうでしたが、調べていくうちにわからないことが増えて行って
取り返しがつかない時がちょくちょくおきます。
一旦諦めて、進んでまたエラーが出たらその時にまた調べることにします。
ということで、今回はここまでです。