【问题标题】:Read TQDM Output From File从文件中读取 TQDM 输出
【发布时间】:2020-08-21 00:42:43
【问题描述】:

这主要是一个一般的 python 问题,我在分布式环境中工作,所以我的工作人员将他们的 stdout 和 stderr 写入共享文件系统上的文件(我无法更改)。我希望我的启动器脚本读取其中一个文件并实时打印出来以粗略跟踪工作人员的进度,每个工作人员都使用 tqdm 输出进度条。我很高兴看到运行 tail -f 的文件正确输出进度条,例如就像我在本地运行 tqdm 时一样,条形图在一行上更新。但是,当我尝试用 python 包装它时,使用以下函数:

def follow(job : submitit.Job) -> Iterator[str]:
    with open(job.paths.stdout) as fo:
        with open(job.paths.stderr) as fe:
            while True:
                lo = fo.readline()
                    
                if lo:
                    yield lo         

                le = fe.readline()
                if le:
                    yield le

                if job.state != 'RUNNING' and not (le or lo):
                    break
                else:
                    time.sleep(1)

loglines = follow(job)
for line in loglines:
    print(line, end='', flush=True)

它不这样做,例如我得到一个换行符,并且通过打印新行来更新进度条,它似乎无法处理 tqdm 正在写入的 \x1b[A 字符。

有没有办法纯粹在 python 中做到这一点?

【问题讨论】:

    标签: python tqdm


    【解决方案1】:

    我能够通过使用读取二进制模式来解决这个问题,使用read 读取文件末尾,然后将生成的字节解码为ascii,而不是 python 3 默认的 UTF-8。更新后的工作跟随功能如下:

    def follow(job : Job) -> Iterator[str]:
        with open(job.paths.stdout, 'rb') as fo:
            with open(job.paths.stderr, 'rb') as fe:
                while True:
                    lo = fo.read().decode('ascii')
                        
                    if lo:
                        yield lo   
    
                    le = fe.read().decode('ascii')
                    if le:
                        yield le
    
                    if job.state != 'RUNNING' and not le and not lo:
                        break
                    else:
                        time.sleep(0.1)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多