python中的raw_input没有按Enter键

Som*_*DOS 22 python user-input

我正在使用raw_inputPython与shell中的用户进行交互.

c = raw_input('Press s or n to continue:')
if c.upper() == 'S':
    print 'YES'
Run Code Online (Sandbox Code Playgroud)

它按预期工作,但用户必须在按's'后按下回车键.有没有办法从用户输入完成我需要的东西,而无需在shell中按Enter键?我正在使用*nixes机器.

Ale*_*lli 16

在Windows下,您需要该msvcrt模块,具体而言,从您描述问题的方式来看,函数msvcrt.getch:

读取按键并返回结果字符.控制台没有任何回应.如果按键尚未可用,此调用将阻止,但不会等待按下Enter键.

(等 - 请参阅我刚才指出的文档).对于Unix,请参阅此配方,以获得构建类似getch函数的简单方法(另请参阅该配方的注释线程中的几个备选方案和c).

  • 直接转到 https://pypi.python.org/pypi/readchar,似乎完成了大部分工作,尽管我无法正确读取 OSX 上的箭头键。 (2认同)

Adr*_*oga 14

实际上在此期间(距本主题开始将近 10 年)出现了一个名为pynput的跨平台模块。在第一次剪辑下方 - 即仅适用于小写的 's'。我已经在 Windows 上测试过它,但我几乎 100% 肯定它应该可以在 Linux 上运行。

from pynput import keyboard

print('Press s or n to continue:')

with keyboard.Events() as events:
    # Block for as much as possible
    event = events.get(1e6)
    if event.key == keyboard.KeyCode.from_char('s'):
        print("YES")
Run Code Online (Sandbox Code Playgroud)


sys*_*out 10

Python不提供开箱即用的多平台解决方案.
如果你在Windows上,你可以尝试使用msvcrt:

import msvcrt
print 'Press s or n to continue:\n'
input_char = msvcrt.getch()
if input_char.upper() == 'S': 
   print 'YES'
Run Code Online (Sandbox Code Playgroud)


Der*_*rth 6

为了获取单个字符,我使用了getch,但我不知道它是否适用于 Windows。


use*_*966 6

诅咒也可以做到这一点:

import curses, time

def input_char(message):
    try:
        win = curses.initscr()
        win.addstr(0, 0, message)
        while True: 
            ch = win.getch()
            if ch in range(32, 127): 
                break
            time.sleep(0.05)
    finally:
        curses.endwin()
    return chr(ch)

c = input_char('Do you want to continue? y/[n]')
if c.lower() in ['y', 'yes']:
    print('yes')
else:
    print('no (got {})'.format(c))
Run Code Online (Sandbox Code Playgroud)


Flu*_*lux 5

类Unix操作系统(包括Linux)的标准库解决方案:

def getch():
    import sys, termios

    fd = sys.stdin.fileno()
    orig = termios.tcgetattr(fd)

    new = termios.tcgetattr(fd)
    new[3] = new[3] & ~termios.ICANON
    new[6][termios.VMIN] = 1
    new[6][termios.VTIME] = 0

    try:
        termios.tcsetattr(fd, termios.TCSAFLUSH, new)
        return sys.stdin.read(1)
    finally:
        termios.tcsetattr(fd, termios.TCSAFLUSH, orig)
Run Code Online (Sandbox Code Playgroud)

这是通过在从终端读取数据之前将终端置于非规范输入模式来实现的。

不回显用户输入的替代解决方案(例如,如果用户按z,z将不会出现在屏幕上):

def getch():
    import sys, termios, tty

    fd = sys.stdin.fileno()
    orig = termios.tcgetattr(fd)

    try:
        tty.setcbreak(fd)  # or tty.setraw(fd) if you prefer raw mode's behavior.
        return sys.stdin.read(1)
    finally:
        termios.tcsetattr(fd, termios.TCSAFLUSH, orig)
Run Code Online (Sandbox Code Playgroud)

使用示例:

print('Press s or n to continue: ', end='', flush=True)
c = getch()
print()
if c.upper() == 'S':
    print('YES')
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,非常需要没有外部库的答案 (3认同)