stdout中的输出在cmd和Python控制台中有所不同
我是Python新手,正在开发一个小程序,可以将给定扩展名的所有文件从一个文件夹及其子文件夹复制到另一个目录。最近我添加了一个简单的进度条和剩余文件的计数器。 问题是,当我从cmd运行它时,计数器从1000到999,cmd在最后一个数字的位置添加了一个零,而不是空格。此外,当程序完成时,剩余的文件计数器应该用“Done”一词代替,而且它也不能很好地工作 我尝试用print替换sys.stdout.write,并尝试不使用f字符串,结果是一样的stdout中的输出在cmd和Python控制台中有所不同,python,python-3.x,cmd,console,ipython,Python,Python 3.x,Cmd,Console,Ipython,我是Python新手,正在开发一个小程序,可以将给定扩展名的所有文件从一个文件夹及其子文件夹复制到另一个目录。最近我添加了一个简单的进度条和剩余文件的计数器。 问题是,当我从cmd运行它时,计数器从1000到999,cmd在最后一个数字的位置添加了一个零,而不是空格。此外,当程序完成时,剩余的文件计数器应该用“Done”一词代替,而且它也不能很好地工作 我尝试用print替换sys.stdout.write,并尝试不使用f字符串,结果是一样的 def show_progress_bar(tota
def show_progress_bar(total, counter=0, length=80):
percent = round(100 * (counter / total))
filled_length = int(length * counter // total)
bar = '=' * filled_length + '-' * (length - filled_length)
if counter < total:
suffix = f'Files left: {total - counter}'
else:
suffix = 'Done.'
sys.stdout.write(f'\rProgress: |{bar}| {percent}% {suffix}')
sys.stdout.flush()
def selective_copy(source, destination, extension):
global counter
show_progress_bar(total)
for foldername, subfolders, filenames in os.walk(source):
for filename in filenames:
if filename.endswith(extension):
if not os.path.exists(os.path.join(destination, filename)):
shutil.copy(os.path.join(foldername, filename), os.path.join(destination, filename))
else:
new_filename = f'{os.path.basename(foldername)}_{filename}'
shutil.copy(os.path.join(foldername, filename), os.path.join(destination, new_filename))
counter += 1
show_progress_bar(total, counter)
程序已完成:
Progress: |================================================================================| 100% Done.
Progress: |================================================================================| 100% Done. left: 100
但在cmd中,我得到了:
程序运行:
Progress: |=========-----------------------------------------------------------------------| 12% Files left: 976
Progress: |=========-----------------------------------------------------------------------| 12% Files left: 9760
程序已完成:
Progress: |================================================================================| 100% Done.
Progress: |================================================================================| 100% Done. left: 100
通常,打印“\r”会将光标返回到行首,但不会擦除任何已写入的内容。因此,如果在“1000”后面加上“\r”再加上“999”,则“1000”中的最后0仍将可见
(我不知道为什么Python控制台中不会出现这种情况。也许它会以不同的方式解释“\r”。如果不确切知道您正在运行什么软件,很难说。)
一种解决方案是在输出后打印两个空格,以确保稍长的旧消息被覆盖。您可能只需要为“Files left:”后缀保留一个空格,因为最多只减少一个字符,但“done”后缀需要更多
if counter < total:
suffix = f'Files left: {total - counter} '
else:
suffix = 'Done. '
如果计数器<总计:
后缀=f'文件左:{total-counter}'
其他:
后缀='Done'
通常,打印“\r”会将光标返回到行首,但不会擦除任何已写入的内容。因此,如果在“1000”后面加上“\r”再加上“999”,则“1000”中的最后0仍将可见
(我不知道为什么Python控制台中不会出现这种情况。也许它会以不同的方式解释“\r”。如果不确切知道您正在运行什么软件,很难说。)
一种解决方案是在输出后打印两个空格,以确保稍长的旧消息被覆盖。您可能只需要为“Files left:”后缀保留一个空格,因为最多只减少一个字符,但“done”后缀需要更多
if counter < total:
suffix = f'Files left: {total - counter} '
else:
suffix = 'Done. '
如果计数器<总计:
后缀=f'文件左:{total-counter}'
其他:
后缀='Done'
您需要“清洁”线路的其余部分。查看这个示例解决方案。您的问题是,您的字符数未知,因为文件总数可能会更改。因此,您需要通过允许最大的预期计数或提前计算进度行的最大长度来计算更改的文件号,以清理该行的其余部分。此外,无需使用sys-use print(“foo”,end=“\r”,flush=True)可能与@fabianegli重复,谢谢您的建议!我不知道可以在打印中使用冲洗。你需要“清洁”该行的其余部分。查看这个示例解决方案。您的问题是,您的字符数未知,因为文件总数可能会更改。因此,您需要通过允许最大的预期计数或提前计算进度行的最大长度来计算更改的文件号,以清理该行的其余部分。此外,无需使用sys-use print(“foo”,end=“\r”,flush=True)可能与@fabianegli重复,谢谢您的建议!我不知道可以在指纹中使用冲水。谢谢你,@Kevin!最后我把你的建议和上面的@fabianegli的建议结合起来,现在效果很好。谢谢你,@Kevin!最后我把你的建议和上面的@fabianegli的建议结合起来,现在效果很好。