gpt4 book ai didi

python - Linux 下的 Python 中未读取输入

转载 作者:太空宇宙 更新时间:2023-11-04 05:45:09 24 4
gpt4 key购买 nike

我一直在使用像 this 这样的类。到目前为止,它对我来说运行良好,但由于我正在轮询来自外部源的输入,因此我的程序并未接受每个键。以下是代码及其输出的粗略示例。

while True:
ch = getch()
print "Queue: " + ch
# Do something #

输出为

Queue: 0
Queue: 01
Queue: 012
3Queue: 012
Queue: 0124

我知道可能有几种解决方案,主要是那些需要在#Do Something#部分下提高代码效率的解决方案。不过,我已将范围缩小到任意两个 getch() 调用之间的空间尽可能最小化的程度。有什么建议吗?

最佳答案

您特意选择了 getch 实现来避免排队并仅获取最新的字符。

您可以通过将 # Do Something # 部分移动到后台线程来更快地提供输入服务,或者使用类似事件循环的实现,在尝试处理队列中的第一个字符之前将所有可用字符排队,等等。但这些都不能保证您获得所有字符。

如果您希望允许角色排队以确保您不会错过任何角色,只是……不要使用旨在不让他们排队的实现。

<小时/>

如果您不需要 getch 在 2 秒后超时,则只需不调用 select 即可做到这一点。这也意味着您不需要 TCSADRAIN。另外,不要调用 setraw,而是尝试仅关闭您关心的标志。禁用 ICANON 足以使其逐字符读取。

这是一个完整的测试:

import select
import sys
import termios
import time
import tty

def getch():
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
new_settings = old_settings[:]
new_settings[3] ~= ~termios.ICANON
try:
termios.tcsetattr(fd, termios.TCSANOW, new_settings)
ch=sys.stdin.read(1)
finally:
termios.tcsetattr(fd, termios.TCSANOW, old_settings)
return ch

while True:
ch = getch()
if ch == '\x03':
break
print "Queue: " + ch
time.sleep(1)

这是输出:

aQueue: a
bcdefgQueue: b
Queue: c
Queue: d
Queue: e
Queue: f
Queue: g
^CTraceback (most recent call last):
File "getch.py", line 24, in <module>
ch = getch()
File "getch.py", line 16, in getch
ch=sys.stdin.read(1)
KeyboardInterrupt
<小时/>

如果您确实想要超时,但又不想丢弃多余的字符,那很简单;只需使用 termios 来设置它,而不是围绕它进行最终运行:

new_settings[-1][termios.VTIME] = 20
new_settings[-1][termios.VMIN] = 0

现在输出如下所示:

aQueue: a
bcdQueue: b
Queue: c
Queue: d
Queue:
Queue:
^CTraceback (most recent call last):
File "getch.py", line 30, in <module>
time.sleep(1)
KeyboardInterrupt
<小时/>

termios 中还有更多选项 - 如果您想要您所使用的实现的无回声功能、^C 吞咽等,请阅读手册页。

此外,如果您想确切了解 setraw 的作用,只需运行以下命令:

import sys, termios, tty

fd = sys.stdin.fileno()
o = termios.tcgetattr(fd)
tty.setraw(fd)
n = termios.tcgetattr(fd)
tcsetattr(fd, termios.TCSANOW, o)

print('iflag : {:10x} {:10x}'.format(o[0], n[0]))
print('oflag : {:10x} {:10x}'.format(o[1], n[1]))
print('cflag : {:10x} {:10x}'.format(o[2], n[2]))
print('lflag : {:10x} {:10x}'.format(o[3], n[3]))
print('ispeed: {:10d} {:10d}'.format(o[4], n[4]))
print('ospeed: {:10d} {:10d}'.format(o[5], n[5]))
print('cc :')
for i, (oo, nn) in enumerate(zip(o[6], n[6])):
print(' {:4d}: {:>10} {:>10}'.format(i, oo, nn))

然后您可以查看 termios Python 模块、联机帮助页和 C header (/usr/include/sys/termios.h),了解每个字段中每个不同位的含义。

关于python - Linux 下的 Python 中未读取输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17034367/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com