程序在python中运行时如何防止用户输入控制台? [复制]
Posted
技术标签:
【中文标题】程序在python中运行时如何防止用户输入控制台? [复制]【英文标题】:How to prevent user input into console when program is running in python? [duplicate] 【发布时间】:2021-04-13 22:18:08 【问题描述】:我正在用 python 制作一个在控制台上运行的游戏。当我退出游戏时,我按下的所有键都会自动输入。我该如何阻止这种情况发生?另外,当我使用input()
函数时,我仍然希望有用户输入。顺便说一下,这是在 Windows 上。
如果你想要代码,这有同样的“问题”:
for _ in range(100000):
print("Hello")
当程序在命令提示符下完成时,会出现:
C:\Users\User>awdsaawdsadwsaasdwaws
基本上,代码运行时按下的任何键。当其他东西也在命令提示符下运行时会发生这种情况,但我想知道如何在 python 中禁用它。
编辑:我一直在挖掘,发现我正在寻找的是刷新或清除键盘缓冲区。我将我的问题标记为与另一个有几个答案的问题重复,但这个问题最适合我:
def flush_input():
try:
import msvcrt
while msvcrt.kbhit():
msvcrt.getch()
except ImportError:
import sys, termios #for linux/unix
termios.tcflush(sys.stdin, termios.TCIOFLUSH)
【问题讨论】:
如果你能提供一些代码就太好了,这样我们就不用猜测了 这似乎不太可能,除非您的程序注册按下的键,然后循环每个按下的键并使用 python 模拟它。但是你会知道为什么会这样。 好吧,从我的推论(因为你还没有提供代码)我会说有打印语句可以打印用户在最后使用input()
输入的所有内容
@Matiiss 控制台中的游戏是蛇游戏。当程序运行时,我希望用户可以使用input()
更改设置。这就是为什么有输入。但除此之外,当你死的时候,你按下的所有键都在下一行,比如C:\Users\User>awdsadwdasdawdasdasdsawdas
正如我所说,您应该提供代码。如果我不知道您在代码中添加了什么,您认为我将如何回答为什么会发生这种情况?
【参考方案1】:
发生这种情况是因为您的计算机注册了击键,并且在控制台上,这些击键在 stdin
输入流中可用。
如果您将脚本保存为test.py
并运行python test.py
并开始输入一些击键,例如abc
,这些字母将在标准输入中。
您的脚本不会读取它们,因为它不会触及该流,因为您没有使用 input()
或任何其他会读取该流的调用。所以你的脚本完成了,字符仍然在标准输入中,提示返回并且 it 读取这些字符,并给出给定的结果:
Hello
Hello
Hello
PS C:\Users\username> abc
为避免这种情况,您可以在脚本末尾读取/刷新输入缓冲区。但是,如果您需要它在所有操作系统和不同的脚本运行模式下工作(直接从 cmd、IDLE、在其他 IDE 中等),这将是非常困难的。
问题是,在您尝试从中读取之前,无法知道标准输入流上是否有输入。但是,如果您尝试从中读取,您的脚本将暂停,直到收到“行尾”或“文件尾”。如果用户只是敲击键,那将不会发生,所以你最终会一直阅读,直到他们敲击 Ctrl+Break 或 Ctrl+C 之类的东西。
这是一种我认为相对稳健的方法,但我建议您在您认为可能使用脚本的场景和环境中对其进行测试:
import sys
import threading
import queue
import os
import signal
for _ in range(100000):
print("Hello")
timeout = 0.1 # sec
def no_input():
# stop main thread (which is probably blocked reading input) via an interrupt signal
# only available for windows in Python version 3.2 or higher
os.kill(os.getpid(), signal.SIGINT)
exit()
# if a sigint is received, exit the main thread (you could call another function to do work first and then exit()
signal.signal(signal.SIGINT, exit)
# input is stored here, until it's dealt with
input_queue = queue.Queue()
# read all available input until main thread exit
def get_input():
while True:
try:
# read input, not doing anything with it
_ = input_queue.get(timeout=timeout)
except queue.Empty:
no_input()
reading_thread = threading.Thread(target=get_input)
reading_thread.start()
# main loop: put any available input in the queue, will wait for input if there is none
for line in sys.stdin:
input_queue.put(line)
# wait for reading thread
reading_thread.join()
它基本上从第二个线程读取输入,允许主线程获取输入并可能对它做一些事情,直到什么都没有,然后它只是告诉主线程退出。请注意,这将导致您的脚本以退出代码 2 退出,这可能不是您想要的。
另请注意,您仍会在屏幕上看到输入,但不会再将其传递到终端:
Hello
Hello
Hello
abc
PS C:\Users\username>
我不知道是否有一种简单的方法可以避免回声,除了在 Linux 上执行stty -echo
之类的操作。您当然可以在脚本结束时调用系统来清除屏幕:
from subprocess import call
from os import name as os_name
call('clear' if os_name =='posix' else 'cls')
【讨论】:
以上是关于程序在python中运行时如何防止用户输入控制台? [复制]的主要内容,如果未能解决你的问题,请参考以下文章