如何读取键盘输入?
- 2025-02-10 08:57:00
- admin 原创
- 72
问题描述:
我想用 Python 从键盘读取数据。我尝试了以下代码:
nb = input('Choose a number')
print('Number%s
' % (nb))
但它不起作用,无论是使用 eclipse 还是在终端中,它总是停止问题。我可以输入一个数字,但之后什么也没有发生。
你知道为什么吗?
解决方案 1:
使用
input('Enter your input:')
如果你使用 Python 3。
如果您想要一个数值,只需将其转换即可:
try:
mode = int(input('Input:'))
except ValueError:
print("Not a number")
如果您使用 Python 2,则需要使用raw_input
而不是input
。
解决方案 2:
看起来你在这里混合了不同的 Python(Python 2.x 与 Python 3.x)......这基本上是正确的:
nb = input('Choose a number: ')
问题是它仅在 Python 3 中受支持。正如 @sharpner 回答的那样,对于旧版本的 Python (2.x),您必须使用该函数raw_input
:
nb = raw_input('Choose a number: ')
如果您想将其转换为数字,那么您应该尝试:
number = int(nb)
...尽管您需要考虑到这可能会引发异常:
try:
number = int(nb)
except ValueError:
print("Invalid number")
如果要使用格式化打印数字,在 Python 3 中str.format()
建议:
print("Number: {0}
".format(number))
而不是:
print('Number %s
' % (nb))
但是这两个选项(str.format()
和%
)在 Python 2.7 和 Python 3 中都有效。
解决方案 3:
非阻塞、多线程示例:
由于键盘输入阻塞(因为input()
函数阻塞)通常不是我们想要做的(我们经常想继续做其他事情),这里有一个非常精简的多线程示例来演示如何继续运行主应用程序,同时在键盘输入到达时仍然读取它们。我在这里的eRCaGuy_PyTerm串行终端程序中使用了这种技术(搜索代码input()
)。
它的工作原理是创建一个在后台运行的线程,不断调用input()
它将收到的任何数据传递到队列。
这样,主线程就可以做任何它想做的事情了,只要队列中有数据,它就从第一个线程接收键盘输入数据。
裸 Python 3 代码示例(无注释):
import threading
import queue
import time
def read_kbd_input(inputQueue):
print('Ready for keyboard input:')
while (True):
input_str = input()
inputQueue.put(input_str)
def main():
EXIT_COMMAND = "exit"
inputQueue = queue.Queue()
inputThread = threading.Thread(target=read_kbd_input, args=(inputQueue,), daemon=True)
inputThread.start()
while (True):
if (inputQueue.qsize() > 0):
input_str = inputQueue.get()
print("input_str = {}".format(input_str))
if (input_str == EXIT_COMMAND):
print("Exiting serial terminal.")
break
# Insert your code here to do whatever you want with the input_str.
# The rest of your program goes here.
time.sleep(0.01)
print("End.")
if (__name__ == '__main__'):
main()
2.与上面相同的 Python 3 代码,但带有大量解释性注释:
"""
read_keyboard_input.py
Gabriel Staples
www.ElectricRCAircraftGuy.com
14 Nov. 2018
References:
- https://pyserial.readthedocs.io/en/latest/pyserial_api.html
- *****https://www.tutorialspoint.com/python/python_multithreading.htm
- *****https://en.wikibooks.org/wiki/Python_Programming/Threading
- https://stackoverflow.com/questions/1607612/python-how-do-i-make-a-subclass-from-a-superclass
- https://docs.python.org/3/library/queue.html
- https://docs.python.org/3.7/library/threading.html
To install PySerial: `sudo python3 -m pip install pyserial`
To run this program: `python3 this_filename.py`
"""
import threading
import queue
import time
def read_kbd_input(inputQueue):
print('Ready for keyboard input:')
while (True):
# Receive keyboard input from user.
input_str = input()
# Enqueue this input string.
# Note: Lock not required here since we are only calling a single Queue method, not a sequence of them
# which would otherwise need to be treated as one atomic operation.
inputQueue.put(input_str)
def main():
EXIT_COMMAND = "exit" # Command to exit this program
# The following threading lock is required only if you need to enforce atomic access to a chunk of multiple queue
# method calls in a row. Use this if you have such a need, as follows:
# 1. Pass queueLock as an input parameter to whichever function requires it.
# 2. Call queueLock.acquire() to obtain the lock.
# 3. Do your series of queue calls which need to be treated as one big atomic operation, such as calling
# inputQueue.qsize(), followed by inputQueue.put(), for example.
# 4. Call queueLock.release() to release the lock.
# queueLock = threading.Lock()
#Keyboard input queue to pass data from the thread reading the keyboard inputs to the main thread.
inputQueue = queue.Queue()
# Create & start a thread to read keyboard inputs.
# Set daemon to True to auto-kill this thread when all other non-daemonic threads are exited. This is desired since
# this thread has no cleanup to do, which would otherwise require a more graceful approach to clean up then exit.
inputThread = threading.Thread(target=read_kbd_input, args=(inputQueue,), daemon=True)
inputThread.start()
# Main loop
while (True):
# Read keyboard inputs
# Note: if this queue were being read in multiple places we would need to use the queueLock above to ensure
# multi-method-call atomic access. Since this is the only place we are removing from the queue, however, in this
# example program, no locks are required.
if (inputQueue.qsize() > 0):
input_str = inputQueue.get()
print("input_str = {}".format(input_str))
if (input_str == EXIT_COMMAND):
print("Exiting serial terminal.")
break # exit the while loop
# Insert your code here to do whatever you want with the input_str.
# The rest of your program goes here.
# Sleep for a short time to prevent this thread from sucking up all of your CPU resources on your PC.
time.sleep(0.01)
print("End.")
# If you run this Python file directly (ex: via `python3 this_filename.py`), do the following:
if (__name__ == '__main__'):
main()
示例输出:
$ python3 read_keyboard_input.py
准备好键盘输入:
hey
input_str = hey
hello
input_str = hello
7000
input_str = 7000
exit
input_str = exit
退出串行终端。
结束。
Python Queue 库是线程安全的:
请注意,Queue.put()
以及Queue.get()
Queue 类的其他方法都是线程安全的!(这与C++ 中标准模板库中的队列和其他容器不同!)由于 Python Queue 类及其方法是线程安全的,这意味着它们实现了线程间操作所需的所有内部锁定语义,因此队列类中的每个函数调用都可以被视为单个原子操作。请参阅文档顶部的注释: https: //docs.python.org/3/library/queue.html(强调添加):
队列模块实现了多生产者、多消费者队列。当信息必须在多个线程之间安全地交换时,它在线程编程中特别有用。此模块中的 Queue 类实现了所有必需的锁定语义。
参考:
* https://www.tutorialspoint.com/python/python_multithreading.htm
* https://en.wikibooks.org/wiki/Python_Programming/Threading
Python:如何从超类创建子类?
[我使用上面介绍的技术和代码的 repo] https://github.com/ElectricRCAircraftGuy/eRCaGuy_PyTerm
相关/交叉链接:
[我的回答] PySerial 非阻塞读取循环
解决方案 4:
我来这里是为了寻找如何阅读单个字符。
根据这个问题的答案,我找到了readchar库。 pip install 之后:
import readchar
key = readchar.readkey()
解决方案 5:
您可以通过使用变量简单地使用 input() 函数。快速示例!
user = input("Enter any text: ")
print(user)