在Python输入中显示默认值是否可编辑?

86

Python是否可以接受这样的输入:

文件夹名称:下载

但是,用户不需要键入“下载”,它已经作为初始值存在。如果用户想将其编辑为“下载s”,则只需添加's'并按Enter即可。

使用常规输入命令:

folder=input('Folder name: ')

我能得到的只是一个空白提示符:

文件夹名称:

有没有一种简单的方法来完成这个任务,我可能忽略了吗?

17个回答

93

标准库函数input()raw_input()没有这个功能。如果你使用Linux,可以使用readline模块来定义一个输入函数,该函数使用预填值和高级行编辑功能:

import readline

def rlinput(prompt, prefill=''):
   readline.set_startup_hook(lambda: readline.insert_text(prefill))
   try:
      return input(prompt)  # or raw_input in Python 2
   finally:
      readline.set_startup_hook()

3
这段内容的意思是:这个程序在Mac OS X上也可能直接使用,只需要单独安装readline或者pyreadline即可。 - jfs
5
在Windows系统中,我们不应该信任。 - Teoman shipahi
1
"pip install pyreadline" 适用于 Windows:https://dev59.com/questions/KG025IYBdhLWcg3wZ1Ny#6024996 - Yavuz
在我的情况下,它在Mac上无法运行,但在Linux上可以。有什么办法让它在Mac上工作吗? - Oleg Yablokov

22

我假设您是指通过命令行实现。我从未见过用于命令行提示的初始值,通常它们的形式如下:

Folder [default] : 

在代码中简单地表示为:

res = raw_input('Folder [default] : ')
res = res or 'default'

或者,您可以尝试使用Python中的curses模块。


12

这在Windows中有效。

import win32console

_stdin = win32console.GetStdHandle(win32console.STD_INPUT_HANDLE)

def input_def(prompt, default=''):
    keys = []
    for c in unicode(default):
        evt = win32console.PyINPUT_RECORDType(win32console.KEY_EVENT)
        evt.Char = c
        evt.RepeatCount = 1
        evt.KeyDown = True
        keys.append(evt)

    _stdin.WriteConsoleInput(keys)
    return raw_input(prompt)

if __name__ == '__main__':
    name = input_def('Folder name: ')
    print
    print name

2
我认为上面的答案只适用于Python 2。print name是一个明显的提示 ;) 对于Windows上的Python 3解决方案,请参见我的类似问题的答案,稍微修改一下代码:https://dev59.com/GV0a5IYBdhLWcg3wipXk#32156249 - mbdevpl
几个成功在Python3.7 Win10上修改运行。Linux的解决方案是什么? - CS QGB

8

我终于找到了一种简单的替代方案,它适用于Windows和Linux。本质上,我正在使用pyautogui模块来模拟用户的输入。在实践中,它看起来像这样:

from pyautogui import typewrite

print("enter folder name: ")
typewrite("Default Value")
folder = input()

示例

警告:

  1. 从理论上讲,用户可以在typewrite完成之前按下键盘上的某个键,在“默认”输入中间插入字符。
  2. pyautogui在无头系统上不稳定,因此请确保提供备用方案以防导入失败。如果出现No module named 'Xlib'错误,请尝试安装python3-xlibpython-xlib软件包(或xlib模块)。在ssh上运行也可能会有问题

一个回退实现示例:

由于缺少X服务器只可能发生在Linux上,因此以下是一种使用sth的答案作为回退的实现:

try:
    from pyautogui import typewrite
    autogui = True
except (ImportError, KeyError):
    import readline
    autogui = False

def rlinput(prompt, prefill=''):
    if autogui:
        print(prompt)
        typewrite(prefill)
        return input()
    else:
        readline.set_startup_hook(lambda: readline.insert_text(prefill))
        try:
            return input(prompt)
        finally:
            readline.set_startup_hook()

4

我建议使用剪贴板来解决这个问题。将剪贴板粘贴到输入行中,根据需要进行编辑,然后按Enter键。变量clpstack用于保护现有的剪贴板内容。此代码适用于Windows。Linux可以使用import clipboard。

import pyperclip as clp
clpstack=clp.paste()
clp.copy("192.168.4.1")
HOST = input("Enter telnet host: ")
clp.copy(clpstack)

3
这是一个不错的简单解决方案。示例可能应该指出用户需要按CTRL-V将默认值放在输入行上,以便进行可能的编辑。 - Steve Lockwood

4

我认为最好的(最简单和最便携)解决方案是结合@rlotun和@Stephen的回答:

default = '/default/path/'
dir = raw_input('Folder [%s]' % default)
dir = dir or default

我喜欢这种方法,因为它允许默认值是可变的。 - Metagrapher

2

我喜欢这个,它在Windows上运行

def inputWdefault(prompt, default):
    bck = chr(8) * len(default)
    ret = input(prompt + default + bck)
    return ret or default

2

最近遇到了这个问题。以上的答案似乎都不完美。因此我进行了一些研究,并发现以下解决方案是最简单的,适用于Windows和Linux:

import keyboard

def input_with_default(prompt_, default_):
    keyboard.write(default_)
    return input(prompt_)

if __name__ == "__main__":
    print(input_with_default("Please enter: ", "hello world"))

1
注意:keyboard不是标准库的一部分。可能这个答案是指https://pypi.org/project/keyboard/。 - matt wilkie

2
我发现PyInquirer非常有用,特别是在经常构建交互式控制台应用程序时。提示用户使用默认可修改值的方式如下:
from PyInquirer import prompt

question = [
    {
        'type': 'input',
        'name': 'first_name',
        'message': 'Name please',
        'default': 'Max'
    }
]

answer = prompt(question)
print('Hello {}'.format(answer['first_name']))

1

我喜欢@MCO采取的方法,所以我重构了代码。我在X Windows和Microsoft Windows 10 WSL 2上使用Microsoft Terminal进行了测试:

def input_with_default(prompt, prefill=''):
    try:
        from pyautogui import typewrite
        print(prompt)
        typewrite(prefill)
        return input()
    except (ImportError, KeyError):
        import readline
        readline.set_startup_hook(lambda: readline.insert_text(prefill))
    try:
        return input(prompt)
    finally:
        readline.set_startup_hook()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接