tqdmとloggingの併用
「tqdmを使用しているときの出力にtqdm.writeではなくてloggingを使いたい!」
そう思うこと、ありますよね?
しかし、loggingを使用して出力したい場合、「print関数をtqdm.writeに置き換えて……」なんてのは出来ません
なので一手間要ります
from tqdm import tqdm
import logging
import sys
class LoggingHandler(logging.Handler):
def __init__(self, level=logging.NOTSET):
super().__init__(level)
def emit(self, record):
try:
msg = self.format(record)
tqdm.write(msg, file=sys.stderr)
self.flush()
except Exception:
self.handleError(record)
logger = logging.getLogger("Log")
logger.setLevel(10)
sh = LoggingHandler()
logger.addHandler(sh)
format = logging.Formatter("%(asctime)s:[%(levelname)s]: %(message)s")
sh.setFormatter(format)
for i in tqdm(array):
# 処理
logger.log(20, "出力")
(途中で「こんなメソッド無いじゃん!」って思うかもしれませんが継承元が持ってるメソッドです)
重要なのはここです
# 重要1つ目
class LoggingHandler(logging.Handler):
def __init__(self, level=logging.NOTSET):
super().__init__(level)
def emit(self, record):
try:
msg = self.format(record)
tqdm.write(msg, file=sys.stderr)
self.flush()
except Exception:
self.handleError(record)
...
# 重要2つ目
sh = LoggingHandler()
logger.addHandler(sh)
通常、loggingでコンソールに出力したい場合はlogging.StreamHandlerを使うと思いますが、コイツでは力量不足なので出来ません
なのでHandlerを自作します
レベルごとに色分けする
「WARNINGだったらメッセージを黄色に、ERRORだったらメッセージを赤色で出力したい!」
そう思うこと、ありますよね?
実はこれ、さっき作ったクラスを少し変えるだけで実現できます
import logging
import sys
class LoggingHandler(logging.Handler):
colors = {"WARNING": "\033[33m{}\033[0m", "ERROR": "\033[31m{}\033[0m"}
def __init__(self, level=logging.NOTSET):
super().__init__(level)
def emit(self, record):
try:
record.msg = LoggingHandler.colors.get(record.levelname, "{}").format(record.msg)
msg = self.format(record)
print(msg, file=sys.stderr)
self.flush()
except Exception:
self.handleError(record)
logger = logging.getLogger("Log")
logger.setLevel(10)
sh = LoggingHandler()
logger.addHandler(sh)
format = logging.Formatter("%(asctime)s:[%(levelname)s]: %(message)s")
sh.setFormatter(format)
ここではWARNINGとERRORのみ色を付けましたが、LoggingHandler.colorsに、エラー名をキー、"色{}\033[0m"を値とした辞書を追加することでその他のレベルにも対応することができます
また、これを活用することで「エラー名のみ色をつける」といったことも可能です
結論
Handlerを自作すると、色んなことができる