可以在Python输入上显示编辑的默认值吗?

Show default value for editing on Python input possible?

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

1
Folder name: Download

但是,用户不是键入"下载",而是将其作为初始值。 如果用户想要将其编辑为"下载",他只需要添加's'并按Enter键。

使用正常输入命令:

1
folder=input('Folder name: ')

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

1
Folder name:

有没有一种简单的方法可以做到这一点,我错过了?


标准库函数input()raw_input()没有此功能。如果您使用的是Linux,则可以使用readline模块定义使用预填充值和高级线编辑的输入函数:

1
2
3
4
5
6
7
8
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()


我假设你的意思是从命令行。我从未见过命令行提示的初始值,它们通常是以下形式:

1
     Folder [default] :

在代码中简单地说:

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

或者,您可以尝试使用Python中的curses模块执行某些操作。


这适用于Windows。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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


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

1
2
3
4
5
import pyperclip as clp
clpstack=clp.paste()
clp.copy("192.168.4.1")
HOST = input("Enter telnet host:")
clp.copy(clpstack)


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

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


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

1
2
3
4
5
from pyautogui import typewrite

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

Example

一句警告:

  • 从理论上讲,用户可以在typewrite完成之前按键,在"默认"输入的中间插入字符。
  • pyautogui在无头系统上是出了名的不可靠,所以make
    确保在导入失败时提供备份解决方案。如果你
    遇到No module named 'Xlib',尝试安装python3-xlib
    python-xlib包(或xlib模块)。在ssh上运行也可以是一个
    问题。
  • 一个示例后备实现:

    由于丢失的x服务器在逻辑上只能在linux上发生,所以这是一个使用sth的答案作为后备的实现:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    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()


    我喜欢这个,它适用于窗户

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

    我们可以使用Tkinter并使用StringVar来执行此操作。限制是输入是通过Tkinter窗口。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    from tkinter import Tk, LEFT, BOTH, StringVar
    from tkinter.ttk import Entry, Frame


    class Example(Frame):
        def __init__(self, parent):
            Frame.__init__(self, parent)
            self.parent = parent
            self.initUI()

        def initUI(self):
            self.parent.title("Entry")
            self.pack(fill=BOTH, expand=1)
            self.contents = StringVar()
            # give the StringVar a default value
            self.contents.set('test')
            self.entry = Entry(self)
            self.entry.pack(side=LEFT, padx=15)
            self.entry["textvariable"] = self.contents
            self.entry.bind('<Key-Return>', self.on_changed)

        def on_changed(self, event):
            print('contents: {}'.format(self.contents.get()))
            return True


    def main():
        root = Tk()
        ex = Example(root)
        root.geometry("250x100+300+300")
        root.mainloop()


    if __name__ == '__main__':
        main()

    不是最好的方法,但为了分享...
    您可以使用Javascript在IPython Notebook中获取所有类型的输入。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    from IPython.display import HTML
    newvar =""
    htm ="""
    <input id="inptval" style="width:60%;" type="text" value="This is an editable default value.">
    <button onclick="set_value()" style="width:20%;">OK</button>

    <script type="text/Javascript">
        function set_value(){
            var input_value = document.getElementById('inptval').value;
            var command ="newvar = '" + input_value +"'";
            var kernel = IPython.notebook.kernel;
            kernel.execute(command);
        }

    """

    HTML(htm)

    在下一个单元格中,您可以使用新变量:

    1
    print newvar

    这不是一个很好的答案,但它是一个解决Windows的工作。尽管我努力尝试,但我无法通过Python Ver 3.5在我的Windows10计算机上使用Readline或pyReadline。所以我写了这个。不是世界上最好的代码,因为我只用了3个月的Python。但它的确有效。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
        import os

        def note_input(defaultvalue):
            #Create a textfile
            txtfile = open("txtfile.txt","w")
            #
            # populate it with the default value
            txtfile.write(defaultvalue)
            txtfile.close()
            #
            # call Notepad
            os.system("notepad.exe txtfile.txt")
            # input("Just holding until notepad is close :") (did not need this line)
            #
            # get the Value Entered/Changed in Notepad
            txtfile = open("txtfile.txt","r")
            func_value = txtfile.read()
            txtfile.close()
            return func_value
        # END DEF

    记事本停止程序运行直到它关闭,因此不需要它下面的input()行。一旦记事本第一次打开并放在我想要它在屏幕上的位置,它就像一个弹出输入窗口。我假设您可以使用任何文本编辑器,如Notepad ++或Scripe或Code Writer等。


    如果这样做,用户将不得不删除现有单词。如果用户点击"返回",提供默认值怎么样?

    1
    2
    3
    >>> default_folder ="My Documents"
    >>> try: folder = input("folder name [%s]:" %default_folder)
    ... except SyntaxError: folder = default_folder