使用Python的日志记录覆盖之前的控制台行

问题描述 投票:0回答:1

我想使用Python的日志库来覆盖之前的控制台行。当进程运行时,它应该在控制台上显示

...
,然后在进程完成后用
OK
覆盖它,如此 Python 代码所示。

import time

for i in range(10):
    print(f'Progress: {i+1}/10 ...', end='')
    time.sleep(1)
    print(f'\rProgress: {i+1}/10  OK')

console output displays ... while it is running, and then overwrites it with OK on the same line once it completes

我想使用

logging
库实现相同的结果,但我当前的解决方案感觉太冗长且不符合 Python 风格。有人有更好的方法吗?谢谢!

import logging
import sys
import time

class OverwriteStreamHandler(logging.StreamHandler):
    def __init__(self, stream, overwrite=False):
        super().__init__(stream)
        self.overwrite = overwrite

    def emit(self, record):
        msg = self.format(record)
        stream = self.stream
        if self.overwrite:
            stream.write('\r' + msg)
        else:
            stream.write(msg)
        stream.flush()

def create_logger(name, overwrite=False):
    handler = OverwriteStreamHandler(sys.stdout, overwrite=overwrite)
    handler.setLevel(logging.DEBUG)
    formatter = logging.Formatter('%(message)s')
    handler.setFormatter(formatter)
    logger = logging.getLogger(name)
    logger.setLevel(logging.DEBUG)
    logger.addHandler(handler)
    return logger

logger1 = create_logger('logger1')
logger2 = create_logger('logger2', overwrite=True)

for i in range(10):
    logger1.info(f'Progress: {i+1}/10 ...')
    time.sleep(1)
    logger2.info(f'Progress: {i+1}/10  Ok\n')
python
1个回答
0
投票

有2个选择: 1-添加带有空终止符的处理程序并手动添加行终止符。 2- 创建一个附加记录器,并在处理程序中配置终止符。

选项1

import logging
import time

logging.basicConfig(level=logging.INFO)

logger1 = logging.getLogger("SO_log")
logger2 = logging.getLogger("SO_log")

ch = logging.StreamHandler()
ch.terminator=''
ch.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
ch.setFormatter(formatter)

logger2.addHandler(ch)
logger2.propagate = False

logger1.info('Started\n')


for i in range(10):
    msg = f'Progress: {i+1:>2}/10 {"..."}\r'
    logger1.info(msg)
    time.sleep(0.21)
    msg = f'Progress: {i+1:>2}/10 {"Ok":>3}\r'
    if i == 10:
        msg += "\n"
    logger1.info(msg)
    # additional delay to get a chance to see the Ok msg
    time.sleep(0.21)

logger1.info('\n')

输出日期和消息的最后 9 个字符将交替出现

2024-12-18 23:44:32,535 - SO_log1 - INFO - Started
2024-12-18 23:44:34,638 - SO_log1 - INFO - Progress: 10/10  Ok

选项2

使用 2 个记录器并在处理程序上设置行终止符

import logging
import time

logging.basicConfig(level=logging.INFO)

logger1 = logging.getLogger("SO_log1")
logger2 = logging.getLogger("SO_log2")

ch1 = logging.StreamHandler()
ch1.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
ch1.setFormatter(formatter)
logger1.addHandler(ch1)
logger1.propagate = False

ch2 = logging.StreamHandler()
ch2.terminator='\r'
ch2.setLevel(logging.INFO)
ch2.setFormatter(formatter)
logger2.addHandler(ch2)
logger2.propagate = False

logger1.info('Started opt 2')

for i in range(10):
    msg = f'Progress: {i+1:>2}/10 {"..."}'
    logger2.info(msg)
    time.sleep(0.21)
    msg = f'Progress: {i+1:>2}/10 {"Ok":>3}'
    #logger2.info(msg)

    if i < 10:
        logger2.info(msg)
    else:
        logger1.info(msg)
    time.sleep(0.21)

logger1.info("\n")

输出2

2024-12-19 00:03:38,262 - SO_log1 - INFO - Started opt 2
2024-12-19 00:03:42,467 - SO_log1 - INFO - Progress: 10/10  Ok

© www.soinside.com 2019 - 2024. All rights reserved.