如何读取键盘输入?

我想用 Python 从键盘上读取数据:

nb = input('Choose a number')
print('Number%s \n' % (nb))

但它不工作,无论是在日食或在终端,它总是停止的问题。我可以输入一个数字,但在没有发生任何事情之后。

你知道为什么吗?

518717 次浏览

使用

input('Enter your input:')

如果你使用 Python 3。

如果你想得到一个数值,只需要转换它:

try:
mode = int(input('Input:'))
except ValueError:
print("Not a number")

如果使用 Python2,则需要使用 raw_input而不是 input

这里似乎混合了不同的 Python (Python 2.x vs Python 3.x) ..。 这基本上是正确的:

nb = input('Choose a number: ')

问题是它只在 Python3中受支持。正如@sharner 回答的那样,对于旧版本的 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}\n".format(number))

而不是:

print('Number %s \n' % (nb))

但是这两个选项(str.format()%)在 Python 2.7和 Python 3中都可以工作。

非阻塞、多线程示例:

由于键盘输入上的阻塞(因为 input()函数块)经常是我们想要做的 没有(我们经常想要继续做其他的事情) ,这里有一个 非常精简的多线程示例来演示 如何继续运行您的主应用程序,同时仍然在键盘输入到达时读取。我在我的 ERCaGuy _ PyTerm串行终端程序 这里(搜索代码 input())中使用了这种技术。

这是通过创建一个线程在后台运行,不断调用 input(),然后将接收到的任何数据传递给队列来实现的。

通过这种方式,主线程可以做任何它想做的事情,只要队列中有内容,就从第一个线程接收键盘输入数据。

1. 裸 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 _ key _ input. py
准备键盘输入:

Input _ str = hey
你好
Input _ str = hello
7000
Input _ str = 7000
出口
Input _ str = exit
正在退出串行终端。
完。

Python Queue 库是线程安全的:

请注意,Queue.put()Queue.get()以及其他 Queue 类方法都是线程安全的!(这是在 C + + 中的标准模板库中的 不像队列和其他容器!)由于 Python Queue 类及其方法是线程安全的,这意味着它们实现了线程间操作所需的所有内部锁语义,因此队列类中的每个函数调用都可以被视为一个单独的原子操作。参见文档顶部的说明: https://docs.python.org/3/library/queue.html(强调添加) :

队列模块实现多生产者、多使用者队列。

参考文献:

  1. Https://pyserial.readthedocs.io/en/latest/pyserial_api.html
  2. 我们要找到他们,我们要找到他们
  3. 我们要找到他们,我们要找到他们
  4. Python: 如何从超类创建子类?
  5. Https://docs.python.org/3/library/queue.html
  6. Https://docs.python.org/3.7/library/threading.html
  7. [我的回购,其中我使用的技术和代码上述] https://github.com/ElectricRCAircraftGuy/eRCaGuy_PyTerm

相关/交叉链接:

  1. [我的回答] PySerial 非阻塞读取循环

您可以通过使用一个变量来简单地使用 input ()函数!

user = input("Enter any text: ")
print(user)

我来这里寻找如何阅读一个字符。

根据对 这个问题的回答,我找到了 里德查尔库:

import readchar


key = readchar.readkey()