从文件中读取 TQDM 输出
Read TQDM Output From File
这主要是一个一般性 python 问题,我在分布式环境中工作,因此我的工作人员将他们的标准输出和标准错误写入共享文件系统上的文件(我无法更改此)。我希望我的启动器脚本读取其中一个文件并实时打印出来以粗略跟踪工作人员的进度,每个工作人员使用 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 中做到这一点?
我能够通过使用读取二进制模式解决这个问题,使用 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)
这主要是一个一般性 python 问题,我在分布式环境中工作,因此我的工作人员将他们的标准输出和标准错误写入共享文件系统上的文件(我无法更改此)。我希望我的启动器脚本读取其中一个文件并实时打印出来以粗略跟踪工作人员的进度,每个工作人员使用 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 中做到这一点?
我能够通过使用读取二进制模式解决这个问题,使用 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)