【问题标题】:Does using print() too much cause it to fail?过多使用 print() 会导致它失败吗?
【发布时间】:2018-01-16 09:09:47
【问题描述】:

TL;DR:

print() 结果未在 Windows 控制台中更新。在 IDLE 中执行良好。即使 Windows 控制台没有更新,程序仍在执行。

背景

我有一个文件,test.py,其中包含:

编辑:包括我用来查看控制台是否正在更新的条件。最终,X 的系列值永远不会在控制台中再次打印,并且控制台永远不会向上滚动(就像在底部生成输出时通常那样)。

count = 0
while True:
    print ("True")
    count += 1
    if count == 10:
            print ("XXXXXXXXX")
            count = 0

当我在cmd.exe 中运行它时,它显然会打印出大量的True

但是,运行大约 25 秒后,它会停止打印,尽管程序仍在运行并且可以在任务管理器中看到。

我有一个程序,其中一些进度指示器最终保持在 50%,即使它们远远超过 50%,仅仅是因为 print() 没有显示在控制台输出中。

编辑:真正的用例问题。

上面的代码只是一个测试文件,用于查看控制台中的打印是否在所有程序中都停止,而不是我正在运行的那个。在实践中,我的程序打印到控制台,看起来像:

line [10] >> Progress 05%

line [10] 不是 真实的,但我只是在这里键入以向您显示 print() 发送到控制台窗口中的该行。随着我的程序继续,它会增加:

line [10] >> Progress 06%
line [10] >> Progress 11%
.
.
.
line [10] >> Progress 50%

每次line [10] 都会被覆盖。我使用 ANSI 转义字符和 colorama 相应地移动控制台光标:

print('\x1b[1000D\x1b[1A')

这会将光标向左移动 1000 列并向上移动 1 行(因此是上一行的开头)。

发生了一些事情,print("Progress " + prog + "%") 不再出现在控制台中,因为最终 Python 的下一个位被执行:

line [11] >> Program Complete...

我验证了放入文件夹的结果。所以程序在控制台没有更新的情况下继续运行。

编辑:这是运行stdout更新的脚本。

def check_queue(q, dates, dct):
    out = 0
    height = 0

    # print the initial columns and rows of output
    # each cell has a unique id 
    # so they are stored in a dictionary
    # then I convert to list to print by subscripting
    for x in range(0, len(list(dct.values())), 3):
        print("\t\t".join(list(dct.values())[x:x+3]))
        height +=1 # to determine where the top is for cursor

    while True:
        if out != (len(dates) * 2):
            try:
                status = q.get_nowait()
                dct[status[1]] = status[2]
                print('\x1b[1000D\x1b[' + str(height + 1) + 'A')

                # since there was a message that means a value was updated
                for x in range(0, len(list(dct.values())), 3):
                    print("\t\t".join(list(dct.values())[x:x+3]))

                if status[0] == 'S' or 'C' or 'F':
                    out += 1
            except queue.Empty:
                pass
    else:
        break

简而言之,我将消息从线程传递到队列。然后我更新一个包含唯一单元 ID 的字典。我更新值,将 Console 中的光标移动到打印列表的左上角位置,然后在上面打印。

问题:

使用stdout时,在一段时间内可以打印多少次有限制吗?

【问题讨论】:

  • 是什么让您认为它停止打印?
  • Python 对进程可以生成多少输出当然没有限制。
  • @user2357112 现在看一下代码块。我用我的测试方式更新了它以确保这一点。最终发生的是X 的系列最终不再出现,并且控制台永远不会向上滚动先前的输出。这让我相信它不再打印了。
  • @user2357112 所以我可能需要问的是“为什么我的 Windows 控制台没有更新 print() 结果?”。想法?
  • Windows 中对 ANSI 转义序列的支持是全新的。那里可能存在错误并非完全不可信。但我们真的非常需要minimal reproducible example。 (强调minimal,即重现问题的smallest程序。)

标签: python windows console


【解决方案1】:

这很可能是一种错觉(可能是因为控制台中有最大的行数限制,然后新的行会替换第一行)。

print 绝对没有限制。您可以通过改变每次迭代的方法来验证这一点,例如计算迭代次数的循环:

import itertools
for i in itertools.count():
    print(i, "True")

【讨论】:

  • 我开始认为可能是达到行数的情况。但是,我在同一位置覆盖行。是重复计算吗?
  • 我不明白你的意思。一些控制台像 FIFO 队列一样工作,当达到某个限制时,它们会丢弃最旧的行以打印最新的行。就像我在答案中提到的那样。但无论如何,如果这不能解决您的问题并解释为什么它不能解决您的问题,您能否更新您的问题?
【解决方案2】:

听起来可能是系统限制,而不是 Python 进程问题?我从来没有遇到过与打印语句(或任何内置函数)相关的“挂起”,但是您可能想查看映射性能和内存使用情况:

High Memory Usage Using Python Multiprocessing

至于你可以在一段时间内打印多少次,这几乎完全取决于系统执行代码的速度。您可以在多个平台上运行一些基准测试(执行时间/执行次数)来测试特定系统规格的性能,但我认为问题的可能原因与系统/环境相关。

【讨论】:

    【解决方案3】:

    我无法在使用 64 位 Python 3.6.2 和 colorama 0.3.9 的 Windows 10 中重现该问题。这是我测试的简单示例:

    import colorama
    colorama.init()
    
    def test(M=10, N=1000):
        for x in range(M):
            print('spam')
        for n in range(N):
            print('\x1b[1000D\x1b[' + str(M + 1) + 'A')
            for m in range(M):
                print('spam', m, n)
    

    每次成功都会覆盖前面的行。这是循环 N (1000) 次的最终输出:

    >>> test()
    spam 0 999
    spam 1 999
    spam 2 999
    spam 3 999
    spam 4 999
    spam 5 999
    spam 6 999
    spam 7 999
    spam 8 999
    spam 9 999
    

    如果此示例对您不适用,请更新您的问题并包括您正在测试的 Windows、Python 和 colorama 版本。

    【讨论】:

    • 我使用的是 Windows 7、Python 3.6.0 和最新版本的 colorama。有趣的是,即使不使用 coloroma 功能,最终标准输出也会在控制台中停止更新(例如问题中的我的while 循环)。
    • 这个答案中的例子怎么样?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-09-24
    • 2023-04-01
    • 1970-01-01
    • 2021-03-08
    • 2010-10-27
    相关资源
    最近更新 更多