Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python进度条日志模块_Python_Logging_Progress Bar - Fatal编程技术网

Python进度条日志模块

Python进度条日志模块,python,logging,progress-bar,Python,Logging,Progress Bar,我在Python中看到了不同的进度条解决方案,但简单的stdout解决方案不适用于我的项目。我有多个类,并使用“日志”模块将信息输出到标准输出。我有一个函数,我想在一行上显示一个进度条,每次刷新缓冲区 简单进度示例: for i in range(100): time.sleep(1) sys.stdout.write("\r%d%%" %i) sys.stdout.flush() 当我尝试通过标准输出写入,然后刷新缓冲区时,要么缓冲区没有刷新,要么进程没有进展。我希望

我在Python中看到了不同的进度条解决方案,但简单的stdout解决方案不适用于我的项目。我有多个类,并使用“日志”模块将信息输出到标准输出。我有一个函数,我想在一行上显示一个进度条,每次刷新缓冲区

简单进度示例:

for i in range(100):
    time.sleep(1)
    sys.stdout.write("\r%d%%" %i)
    sys.stdout.flush()

当我尝试通过标准输出写入,然后刷新缓冲区时,要么缓冲区没有刷新,要么进程没有进展。我希望避免一些线程或复杂的过程,使这成为可能。有人有更好的方法来实现这一点吗?

如果您知道进度条总是要写入标准输出,那么您应该使用
打印而不是记录器。请参阅文档

,您可以使用:

导入日志
导入时间
导入彩色日志
从TQM导入TQM
类TqdmHandler(logging.StreamHandler):
定义初始化(自):
logging.StreamHandler.\uuuuu init\uuuuuu(self)
def排放(自我,记录):
msg=self.format(记录)
tqdm.write(msg)
如果名称=“\uuuuu main\uuuuuuuu”:
对于tqdm中的x(范围(100)):
logger=colorlog.getLogger(“MYAPP”)
logger.setLevel(logging.DEBUG)
handler=TqdmHandler()
handler.setFormatter(colorlog.ColoredFormatter(
“%(日志颜色)s%(名称)s |%(asctime)s |%(levelname)s |%(消息)s”,
datefmt=“%Y-%d-%d%H:%M:%S”,
原木颜色={
“调试”:“青色”,
“信息”:“白色”,
“成功:”:“绿色”,
“警告”:“黄色”,
“错误”:“红色”,
“关键”:“红色,背景为白色”},)
logger.addHandler(处理程序)
debug(“内部子任务:+str(x))
时间。睡眠(.5)
我是这样解决的:

import logging
import time
from tqdm import tqdm
import io

class TqdmToLogger(io.StringIO):
    """
        Output stream for TQDM which will output to logger module instead of
        the StdOut.
    """
    logger = None
    level = None
    buf = ''
    def __init__(self,logger,level=None):
        super(TqdmToLogger, self).__init__()
        self.logger = logger
        self.level = level or logging.INFO
    def write(self,buf):
        self.buf = buf.strip('\r\n\t ')
    def flush(self):
        self.logger.log(self.level, self.buf)

if __name__ == "__main__":
    logging.basicConfig(format='%(asctime)s [%(levelname)-8s] %(message)s')
    logger = logging.getLogger()
    logger.setLevel(logging.DEBUG)

    tqdm_out = TqdmToLogger(logger,level=logging.INFO)
    for x in tqdm(range(100),file=tqdm_out,mininterval=30,):
        time.sleep(.5)
输出

2016-12-19 15:35:06 [INFO    ] 16%|#####9                                | 768/4928 [07:04<40:50,  1.70it/s]
2016-12-19 15:36:07 [INFO    ] 18%|######6                               | 865/4928 [08:04<40:34,  1.67it/s]

2016-12-19 15:35:06[INFO]16%|#####9 | 768/4928[07:04我找不到一个很好的解决方案,所以我写了一篇文章来处理它。基本上,它改变了终端的滚动区域,因此日志记录在进度条上方完成,而不必重新绘制进度条每次你想写入标准输出时。这样你就可以在不需要修改的情况下,随心所欲地写入终端


清理这些提案上的代码,这是正确的实施,除了
tqdm
(也已发布)之外,没有任何外部依赖性:

导入日志
从TQM导入TQM
类TqdmLoggingHandler(logging.StreamHandler):
“”“通过记录器到控制台的输出避免TQM进度条中断”“”
#请参阅logging.StreamHandler.eval方法:
# https://github.com/python/cpython/blob/d2e2534751fd675c4d5d3adc208bf4fc984da7bf/Lib/logging/__init__.py#L1082-L1091
#和tqdm.write方法:
# https://github.com/tqdm/tqdm/blob/f86104a1f30c38e6f80bfd8fb16d5fcde1e7749f/tqdm/std.py#L614-L620
def排放(自我,记录):
尝试:
msg=self.format(记录)
tqdm.write(消息,结束=self.terminator)
除递归错误外:
提升
除例外情况外:
自处理错误(记录)
测试:

导入时间
log=logging.getLogger(_名称__)
log.setLevel(logging.INFO)
log.addHandler(TqdmLoggingHandler())
#^——假设这是向sys.stdout发送消息的唯一处理程序。
#如果其他处理程序输出到sys.stdout(不带tqdm.write),
#进度条将被这些输出中断
对于tqdm中的i(范围(20)):
log.info(f“循环{i}”)
睡眠时间(0.1)

使用“打印”的问题它在新行上抛出每个值,不再使输出成为进度条。STDOUT应该刷新缓冲区并在现有行上写入,但在同时进行日志记录的代码中使用它时,这似乎不起作用。请注意,我没有将任何日志记录模块语法包装在进度条代码上。使用您需要的确切代码在上面的帖子中,我看到输出被替换到位。您是否看到每一个数字都出现在一个新行上?这是否回答了问题?这对我来说不起作用。我想,您可以尝试这样做:
datefmt='%Y-%d-%d%H:%M:%S'
应该像这样:
datefmt='%Y-%M-%d%H:%M:%S'
(月)?只是好奇进度条
######9
末尾的数字是从哪里来的,我们如何摆脱它?这很好,但每次更新都会打印一行新行,或者?所有数字都是“小数”。事实上,记录器总是打印在新行上。如果您登录到文件,这很好。如果您不想要新行(带有时间戳),那么您就不需要使用logger。我刚刚发现了这个模块,这正是我所需要的!谢谢您。删除了关于Windows的评论。Windows支持添加到版本1.3.0中,这在Jupyter笔记本中有效吗?版本1.10.0添加了对Jupyter笔记本的支持
import logging
import time
import enlighten

# Setup logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger()

# Setup progress bar
manager = enlighten.get_manager()
pbar = manager.counter(total=100, desc='Ticks', unit='ticks')

for i in range(1, 101):
    logger.info("Processing step %s" % i)
    time.sleep(.2)
    pbar.update()