实现Python程序的运行进程、使用时间和剩余时间的显示功能需要使用Python标准库中的time模块和os模块。下面是一个完整的实现代码和详细的攻略说明:
import time
import os
def get_terminal_size():
"""
获取终端窗口大小
"""
env = os.environ
def ioctl_GWINSZ(fd):
try:
import fcntl, termios, struct
cr = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ, '1234'))
except:
return None
return cr
cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2)
if not cr:
try:
fd = os.open(os.ctermid(), os.O_RDONLY)
cr = ioctl_GWINSZ(fd)
os.close(fd)
except:
pass
if not cr:
cr = (env.get('LINES', 25), env.get('COLUMNS', 80))
return int(cr[1]), int(cr[0])
def format_time(seconds):
"""
格式化时间,将秒数转换为 HH:MM:SS 格式
"""
m, s = divmod(int(seconds), 60)
h, m = divmod(m, 60)
return f"{h:02d}:{m:02d}:{s:02d}"
def progress_bar(current, total, start_time, bar_width=None):
"""
显示进度条,并计算出剩余时间和预计完成时间
"""
if bar_width is None:
bar_width, _ = get_terminal_size()
bar_width -= 30
percent = current / total
elapsed_time = time.time() - start_time
eta = elapsed_time * (total - current) / current
prefix = f"{current}/{total} "
suffix = f" [{percent*100:.1f}%] | Time: {format_time(elapsed_time)} / ETA: {format_time(eta)}"
suffix_length = len(suffix)
bar_length = bar_width - len(prefix) - suffix_length
filled_length = int(bar_length * percent)
bar = "#" * filled_length + "-" * (bar_length - filled_length)
print(f"\r{prefix}{bar}{suffix}", end="", flush=True)
def main():
total = 100
start_time = time.time()
for i in range(total):
progress_bar(i+1, total, start_time)
time.sleep(0.1)
print()
if __name__ == "__main__":
main()
解释如下:
- 首先,使用get_terminal_size()函数获取终端窗口大小,以便决定进度条的宽度(默认为窗口宽度减去固定前缀和后缀的总长度)。该函数的实现参考了 stackoverflow 上的一篇问题的回答。
- format_time()函数用于将用秒数表示的时间格式化为HH:MM:SS的字符串形式。
- progress_bar()函数用于显示进度条。它需要传入进度条的当前进度、总进度、开始时间,以及可选的进度条宽度(如果没有传入宽度,则根据终端窗口大小自动计算)。该函数首先计算出进度条长度,然后将已完成部分和未完成部分用#和-表示,拼接起来。剩余时间和预计完成时间由总共已花费时间和已完成进度计算得出,并根据format_time函数格式化为字符串。prefix和suffix分别表示进度条前缀和后缀的内容。
- 主程序main()函数用于演示进度条的使用。它首先设定总共需要完成的进度总数,然后在一个循环中依次更新进度条的进度,以及计算剩余时间和预计完成时间。
- 最后,如果程序是直接运行的,则调用main()函数。
下面是两个使用进度条显示功能的示例:
import time
def expensive_operation():
"""
一些耗时较长的操作
"""
time.sleep(2)
def main1():
total = 10
start_time = time.time()
for i in range(total):
expensive_operation()
progress_bar(i+1, total, start_time)
print()
def main2():
total = 100
start_time = time.time()
for i in range(total):
progress_bar(i+1, total, start_time, bar_width=60)
time.sleep(0.1)
print()
if __name__ == "__main__":
main1()
main2()
在main1中,进度条的宽度是根据终端窗口大小动态计算的。在main2中,通过传入bar_width参数,手动指定宽度为60。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:python程序运行进程、使用时间、剩余时间显示功能的实现代码 - Python技术站