【问题标题】:Python command line print on the same linesPython 命令行打印在同一行
【发布时间】:2016-05-31 02:36:05
【问题描述】:

有很多关于在同一行打印的问题,但没有关于在终端的同一行打印多行的问题。

例如:

ogeno@OH-ogeno-MBP:~|⇒ python my_script.py
Process 1: 5%
Process 2: 14%
Process 3: 55%

我希望这些流程的进度在同一行上更新,而不是一遍又一遍地打印。我查看了其他说使用回车符\r 和sys.stdout.flush() 的问题,但它似乎并没有改变插入符号上一行,只是到当前行的末尾。

编辑:我的问题不同,因为它与在终端的同一行上打印多行有关。如果只有一行就很容易了。

【问题讨论】:

  • 请分享一个代码 sn-p 看看你是如何从 my_script.py 处理这个的
  • 对此的明智解决方案是让您的控制进程收集状态信息并打印出来。
  • @glls 我不处理这个。这只是我想要的一个例子
  • @schwobaseggl 我不想使用那个 curses 模块。我只想用普通的 ole python 来做

标签: python shell terminal


【解决方案1】:

这可以通过使用退格键轻松完成。以下是在同一行打印百分比的示例代码。

import time
print "Work in progress(0%%)", # Python 2 print without newline
for work_done in range(10):
    print "\b\b\b\b\b%2d%%)" % work_done, # Backspace then overwrite
    time.sleep(1)

【讨论】:

  • 这不是我想要的
【解决方案2】:

一种方法是使用ANSI escape-code "\033[F" 转到上一行的开头。以下在我的所有终端中运行良好,只需从当前终端位置写入接下来的两行:

import time
import sys

progress_1 = 'Process 1: {}%'
progress_2 = 'Process 2: {}%'
print
print

for i in range(100):
    sys.stdout.write('\033[F')
    sys.stdout.write('\033[F')
    print(progress_1.format(i))
    print(progress_2.format(i))
    time.sleep(0.02)

【讨论】:

  • 当我运行它时,这给了我一个奇怪的结果。一些打印语句写在我的主终端行上方。
  • 然后屏幕清除不起作用。我假设你不是在 Linux 上工作。
  • 我在 Mac 上。无论如何,我不想清除屏幕,有什么办法可以解决这个问题
  • @Ogen 我添加了一些更多独立于系统的终端清除代码。
  • @Ogen 我添加了一些无需清除终端即可工作的代码。
【解决方案3】:

对于python 2.7,你可以使用,

print 2%, 3% # Using comma will print it in same line

对于 python 3.x

print('2%', end=" ")

或者您可以使用 sys.stdout.write 来使用 sys.stdout.flush() 请检查我下面的代码,我已经创建了一个演示进度条。

"""ProgressBar Module."""

import sys
import time


class ProgressBar(object):
    """Main class for the ProgressBa."""

    DEFAULT_BAR_LENGTH = float(30)

    def __init__(self, start=0, step=1):
        """Init for the class."""
        self.end = ProgressBar.DEFAULT_BAR_LENGTH
        self.start = start
        self.step = step
        self.total = self.end - self.start
        self.counts = self.total / self.step
        self._barLength = ProgressBar.DEFAULT_BAR_LENGTH

        self.set_level(self.start)
        self._plotted = False

    def set_level_old(self, level, initial=False):
        """Setting Level."""
        self._level = level
        if level < self.start:
            self._level = self.start
        if level > self.end:
            self._level = self.end

        self._ratio = float(
            self._level - self.start) / float(self.end - self.start)
        self._levelChars = int(self._ratio * self._barLength)

    def set_level(self, level, initial=False):
        """Setting Level."""
        self._level = level
        if level < self.start:
            self._level = self.start
        if level > self.end:
            self._level = self.end

        self._ratio = float(self._level) / float(self._barLength)
        self._levelChars = int(self._ratio * self._barLength) * self.step

    def plot_progress(self):
        """Plotting the bar."""
        sys.stdout.write("\r  %3i%%  |%s%s|" % (
            int(self._ratio * self.step * 100.0),
            u'\u2588' * int(self._levelChars),
            ' ' * int(self._barLength - self._levelChars),
        ))
        sys.stdout.flush()
        self._plotted = True

    def set_and_plot(self, level):
        """Call the plot."""
        old_chars = self._levelChars
        self.set_level(level)
        if (not self._plotted) or (old_chars != self._levelChars):
            self.plot_progress()

    def __del__(self):
        """Del for the class."""
        sys.stdout.write("\n")

if __name__ == "__main__":

    pb = ProgressBar(0, 1)

    curProgress = 0
    pb.plot_progress()
    while curProgress <= pb.counts:
        pb.set_and_plot(curProgress)
        curProgress += 1
        time.sleep(0.1)

    del pb

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-08-18
    • 1970-01-01
    • 1970-01-01
    • 2012-02-28
    • 1970-01-01
    • 2015-04-29
    • 2021-12-29
    • 2014-03-01
    相关资源
    最近更新 更多