如何使用Threading在Python的两个不同地方打印?

问题描述 投票:0回答:1

所以我在 Windows 上,使用多线程和日期时间,并且很幸运在终端的右上角有一个恒定的时钟。为了在右侧终端中显示时钟,我使用了一个函数,我称之为

displayTime
。这是该函数的代码:

from blessed import Terminal
from datetime import datetime


term = Terminal()

def displayTime():
    print(term.home)
    loc = term.get_location()
    while True:
        currentTime = datetime.now()
        a = datetime(currentTime.year, currentTime.month, currentTime.day, currentTime.hour, currentTime.minute, currentTime.second)
        with term.location():
            print(term.move_y(loc[0]))
            print(str(a))
        time.sleep(1)

现在可以了,但我无法做任何其他事情,例如

print()
input()
。所以我找到了线程,理论上,它应该允许我运行其他代码。

所以我创建了一个线程:

timethread = threading.Thread(target=displayTime)
timethread.start()

并测试了一下,效果是一样的。但是,当我添加这一行时:

input("Testing multithreading >> ")

尝试写点东西,但没有成功。事实上,时钟消失了,我无法输入任何文字。我现在正在寻找仍然有输入以及时钟的方法。

python windows multithreading python-multithreading
1个回答
0
投票

终端的所有输入和输出都通过两个(好吧,计算 stderr 为 3 个)数据流进行 - 允许定位文本、设置颜色等的库在这些流上嵌入特殊代码(称为“ANSI 代码”——Windows CMD 除外,其中属性由旁路 API 设置),以便后续打印的字符在新位置或更改属性。

当从另一个线程打印时,即使包含“打印”的代码的处理可能是并发的,数据内容输出也会进入同一个流(默认为

sys.stdout

那么,回答一个通用问题“如何使用线程在两个不同的地方进行 Python 打印?” - 这是可以做到的,但只能通过对 stdout 进行特殊处理,通过将内置

print
函数(或者更确切地说,
sys.stdout
本身)替换为一个线程感知对象,该对象“知道”保留每个线程的最终状态线。它最终必须解析和理解 ANSI 序列,并将终端和光标状态恢复到每个打印线程。 所以,可行,但绝对是一个主要项目。

另一方面,由于您使用的是“blessed”库,它可能提供自己的调用以允许并行打印和数据输入以显示其时钟 - 我们可以检查它的文档并了解它是如何完成的。如果它是在考虑多线程的情况下构建的,它可能会为打印/输入提供线程安全的 API - 否则,它可能会为单线程并发提供基于事件的系统,与 asyncio 不同(或可能基于) -你必须相应地编写你的代码。

哦好吧 - https://blessed.readthedocs.io/en/latest/keyboard.html - 对此感到抱歉,它将终端转换为无缓冲模式,以便能够对每次击键做出反应(而不是必须等待“输入”)并且似乎没有提供与“输入”等效的内容。您必须使用内置的“inkey()”调用来组装自己的。

我建议您使用不同的库进行终端访问:有 terminedia https://pypi.org/project/terminedia/ (我自己的项目,尽管目前记录不足),文本 https://textual.textualize .io/(更完整),甚至Python的内置“curses”https://docs.python.org/3/howto/curses.html(不在Windows上):所有这三个都可以完成复杂的任务在屏幕固定位置更新手表时输入文本。

© www.soinside.com 2019 - 2024. All rights reserved.