我正在尝试将用户输入输入到 python 中。但是,如果用户使用 [Home] 或 Ctrl+A 或 Ctrl+k(典型的 shell 命令)等键,他们会得到代表该键的字符,而不是预期的行为。
我目前有:
data = input("Enter your data here: ").strip()
但是,如果用户使用 Ctrl+A 转到行首,则会在屏幕上打印一个 ^A
字符作为输入的一部分。
有没有办法让我以允许用户使用 bash 组合键(例如 Ctrl+A)的方式获取输入?
最佳答案
简短的版本是只需将 import readline
添加到脚本顶部,它就会神奇地起作用。
更具体地说,readline
库提供了 libreadline
的包装器,它与让您的 bash
shell 或 Python 交互式解释器(就此而言)进行奇特的输入编辑的库相同。
因此,您可以直接使用readline
。如果您想做任何奇特的事情,您应该阅读文档,还可以参阅 rlcompleter
.
但对于像这样的简单情况:默认情况下,只需导入 readline
就会(实际上)为您修补 input
,* 这就是您所需要的。
因此,假设用户(及其发行版)使用默认设置,他们将能够使用在 bash 中使用的相同 emacs 风格的击键。 (而且,如果他们更改了设置,大概他们希望能够在您的程序中使用这些设置,而不仅仅是在 bash 中。)
唯一的问题是,只有在构建 Python 时存在 libreadline
时,这才有效:
- 在大多数 Linux 和 *BSD 系统上,这不是问题。**
- 在 OS X 上,这会成为一个问题,但 Python 提供了一种使用 BSD
libedit
的解决方法,Apple 已将其包含在内。*** - 在 Windows 上,如果您在普通的
cmd.exe
“DOS 框”内运行,您会自动获得 DOS 风格的行编辑,并且无法获得更好的结果...但幸运的是,Windows 用户不知道他们错过了什么。 :)
* 如果您想知道它在幕后是如何工作的,input
底层的代码被巧妙地设计为由 readline
和 IDLE Hook ,在这种方式足够灵活,您甚至可以做一些漂亮的事情,例如将其集成到 asyncio
事件循环中。因此,readline
并没有真正修补input
;相反,它只是注册一个钩子(Hook)。这很酷,值得阅读源代码,但与您的问题无关。
** 如果是这样,除了安装 libreadline
并重建 Python 之外,您无能为力。在 *BSD 上,我猜您可以配置 Python 来构建 OS X libedit
包装器,但我不知道您为什么要麻烦。
*** 如果您使用的是 Apple 或(直到最近)python.org 的预构建 Python,您将使用此解决方法。大多数应用程序和大多数用户不会受到这种差异的影响,但它可能会带来一些烦恼。强制解决这些烦恼的方法是依赖 PyPI 上较新版本的 readline
,如果您的用户尚未安装 libreadline
,该版本将会失败。
关于python 获取不带 ctrl 字符 (^) 的输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25901438/