【问题标题】:Show default value for editing on Python input possible?可以在 Python 输入上显示用于编辑的默认值吗?
【发布时间】:2011-02-01 18:02:00
【问题描述】:

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

文件夹名称:下载

但不是用户键入“下载”,而是作为初始值存在。如果用户想将其编辑为“下载”,他只需添加一个“s”并按 Enter。

使用普通输入命令:

folder=input('Folder name: ')

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

文件夹名称:

有没有我想念的简单方法来做到这一点?

【问题讨论】:

    标签: python input


    【解决方案1】:

    尝试使用“f-string”和“or”的组合,比如:

    default_name = "that_folder"
    
    this_folder = input(f"Folder name: ({default_name}) ") or default_name
    print(this_folder)
    

    如果您在未输入文件夹名称的情况下按 Return 键,将假定为 default_name。

    【讨论】:

      【解决方案2】:

      如果您正在编写 CLI,您可能需要考虑为此使用 python-click 库。

      您将使用以下代码实现您的目标:

      import click
      
      user_input = click.prompt(text="Folder name", default="Download")
      print(f"{user_input=}")
      

      如果你运行这段代码,并且什么都不输入,那么你会得到:

      $ python3 cli_code.py
      Folder name [Download]: 
      user_input='Download'
      

      如果你运行这段代码,然后输入“my-dir”,你会得到:

      $ python3 cli_code.py
      Folder name [Download]: my-dir
      user_input='my-dir'
      

      【讨论】:

        【解决方案3】:

        最近遇到了这个问题。以上答案似乎都不是完美无缺的。所以我做了一些研究,发现以下解决方案是最简单的,并且适用于 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"))
        

        【讨论】:

          【解决方案4】:

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

          Folder [default] : 
          

          代码中的内容很简单:

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

          或者,您可以尝试使用 Python 中的 curses 模块来做一些事情。

          【讨论】:

            【解决方案5】:

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

            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()
            

            【讨论】:

              【解决方案6】:

              我发现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']))
              

              【讨论】:

                【解决方案7】:

                我终于找到了一个适用于 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 can also be a problem

                后备实现示例:

                由于缺少 X-server 在逻辑上只能发生在 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()
                

                【讨论】:

                  【解决方案8】:

                  标准库函数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()
                  

                  【讨论】:

                  【解决方案9】:

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

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

                  【讨论】:

                    【解决方案10】:

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

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

                    【讨论】:

                    • 这是一个不错的简单解决方法。该示例可能应该指出,用户需要执行 CTRL-V 以将默认值放在输入行上,使其可用于可能的编辑。
                    【解决方案11】:

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

                    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()
                    

                    【讨论】:

                      【解决方案12】:

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

                          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 等。

                      【讨论】:

                        【解决方案13】:

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

                        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);
                            }
                        </script>
                        """
                        HTML(htm)
                        

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

                        print newvar
                        

                        【讨论】:

                          【解决方案14】:

                          这适用于 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
                          

                          【讨论】:

                          • 我认为上面的答案仅适用于 Python 2。print name 是一个致命的赠品;)对于 Windows 的 Python 3 解决方案,请参阅我对类似问题的回答,代码稍作修改:@ 987654321@
                          • 一些修改在python3.7 win10下成功运行。 Linux 的解决方案是什么?
                          【解决方案15】:

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

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

                          【讨论】:

                          • 我喜欢这种方法,因为它允许默认值是可变的。
                          【解决方案16】:

                          如果您这样做,用户将不得不删除现有单词。如果用户点击“return”,那么提供一个默认值呢?

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

                          【讨论】:

                            猜你喜欢
                            • 2010-11-18
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            相关资源
                            最近更新 更多