前言:因为嫌弃通过参数启动过于繁琐,并且对于需要进行分支选择的情况不好处理,想使用命令行按键菜单的形式给用户做选择,结果居然发现python没有提供现成的API,于是研究了一些解决方案。
方案一、pygame
这是百度出来的大多数答案,个人不是很推荐,首先pygame是用来做游戏的,提供了太多额外的功能,而不是单纯的键盘响应,过于臃肿,好处是游戏库的多平台适配一定是没问题的,anyway,如果你还是要用的话,示例代码如下:
import pygame
while True:
for event in pygame.event.get():
if event.type == pygame.KEY_DOWN:
if event.unicode == '':
print('#', event.key, event.mod)
else:
print(event.unicode, event.key.event.mod)
方案二、keyboard
参考stack overflow,可以使用keyboard库:
import keyboard # using module keyboard
while True: # making a loop
try: # used try so that if user pressed other than the given key error will not be shown
if keyboard.is_pressed('q'): # if key 'q' is pressed
print('You Pressed A Key!')
break # finishing the loop
except:
break # if user pressed a key other than the given key the loop will break
然而这个库有个问题是linux系统下面需要root权限,为了确保多平台稳定性,我还是没有用它,如果你确保程序是Windows环境下运行或者你的linux运行环境允许root那么keyboard库是一个比较方便的选择。
方案三、getkey
同参考stack overflow,下面有人贴出了另一个库:getkey,是对C原生getchar的封装,在linux下不存在需要root权限的问题:
from getkey import getkey
while True: # Breaks when key is pressed
key = getkey()
print(key) # Optionally prints out the key.
然而这个库有个问题,在Windows下会报错,因为它的getchars返回值在Windows下是bytes类型,而它的代码里用了+=来进行字符串拼接,这会抛出类型不匹配的问题,该段代码的本意应该是需要把bytes类型解码的,所以你可以手动修改那段代码:
...
def getkey(self, blocking=True):
buffer = ''
for c in self.getchars(blocking):
#下面两行代码是我手动添加的
if type(c) == bytes:
c = c.decode('utf-8')
buffer += c #就是这里报错
if buffer not in self.keys.escapes:
break
...
如此,getkey就可以在多平台上正确运行了,如果不想动site package里面的代码,那么在Windows平台使用keyboard,在linux使用getkey也是一个可行的方案。
除了以上三个module,还有很多第三方库可以读取键盘事件,大多是Windows下才能使用或者代码不够简洁之类的,在此不多赘述。