I'm using Python 2.7's raw_input
to read from stdin.
I want to let the user change a given default strin开发者_运维技巧g.
Code:
i = raw_input("Please enter name:")
Console:
Please enter name: Jack
The user should be presented with Jack
but can change (backspace) it to something else.
The Please enter name:
argument would be the prompt for raw_input
and that part shouldn't be changeable by the user.
You could do:
i = raw_input("Please enter name[Jack]:") or "Jack"
This way, if user just presses return without entering anything, "i" will be assigned "Jack".
Python2.7 get raw_input and set a default value:
Put this in a file called a.py:
import readline
def rlinput(prompt, prefill=''):
readline.set_startup_hook(lambda: readline.insert_text(prefill))
try:
return raw_input(prompt)
finally:
readline.set_startup_hook()
default_value = "an insecticide"
stuff = rlinput("Caffeine is: ", default_value)
print("final answer: " + stuff)
Run the program, it stops and presents the user with this:
el@defiant ~ $ python2.7 a.py
Caffeine is: an insecticide
The cursor is at the end, user presses backspace until 'an insecticide' is gone, types something else, then presses enter:
el@defiant ~ $ python2.7 a.py
Caffeine is: water soluable
Program finishes like this, final answer gets what the user typed:
el@defiant ~ $ python2.7 a.py
Caffeine is: water soluable
final answer: water soluable
Equivalent to above, but works in Python3:
import readline
def rlinput(prompt, prefill=''):
readline.set_startup_hook(lambda: readline.insert_text(prefill))
try:
return input(prompt)
finally:
readline.set_startup_hook()
default_value = "an insecticide"
stuff = rlinput("Caffeine is: ", default_value)
print("final answer: " + stuff)
More info on what's going on here:
https://stackoverflow.com/a/2533142/445131
In dheerosaur's answer If user press Enter to select default value in reality it wont be saved as python considers it as '' string so Extending a bit on what dheerosaur.
default = "Jack"
user_input = raw_input("Please enter name: %s"%default + chr(8)*4)
if not user_input:
user_input = default
Fyi .. The ASCII value
of backspace is 08
I only add this because you should write a simple function for reuse. Here is the one I wrote:
def default_input( message, defaultVal ):
if defaultVal:
return raw_input( "%s [%s]:" % (message,defaultVal) ) or defaultVal
else:
return raw_input( "%s " % (message) )
On platforms with readline
, you can use the method described here: https://stackoverflow.com/a/2533142/1090657
On Windows, you can use the msvcrt module:
from msvcrt import getch, putch
def putstr(str):
for c in str:
putch(c)
def input(prompt, default=None):
putstr(prompt)
if default is None:
data = []
else:
data = list(default)
putstr(data)
while True:
c = getch()
if c in '\r\n':
break
elif c == '\003': # Ctrl-C
putstr('\r\n')
raise KeyboardInterrupt
elif c == '\b': # Backspace
if data:
putstr('\b \b') # Backspace and wipe the character cell
data.pop()
elif c in '\0\xe0': # Special keys
getch()
else:
putch(c)
data.append(c)
putstr('\r\n')
return ''.join(data)
Note that arrows keys don't work for the windows version, when it's used, nothing will happen.
For windows users with gitbash/msys2
or cygwin
you can use it's built in readline through python subprocess. It is a sort of hack but works quite well and doesn't require any third party code. For personal tools this works really well.
Msys2 specific: If you want ctrl+c to immediately exit, you will need to run your program with
winpty python program.py
import subprocess
import shlex
def inputMsysOrCygwin(prompt = "", prefilled = ""):
"""Run your program with winpty python program.py if you want ctrl+c to behave properly while in subprocess"""
try:
bashCmd = "read -e -p {} -i {} bash_input; printf '%s' \"$bash_input\"".format(shlex.quote(prompt), shlex.quote(prefilled))
userInput = subprocess.check_output(["sh", "-c", bashCmd], encoding='utf-8')
return userInput
except FileNotFoundError:
raise FileNotFoundError("Invalid environment: inputMsysOrCygwin can only be run from bash where 'read' is available.")
userInput = ""
try:
#cygwin or msys2 shell
userInput = inputMsysOrCygwin("Prompt: ", "This is default text")
except FileNotFoundError:
#cmd or powershell context where bash and read are not available
userInput = input("Prompt [This is default text]: ") or "This is default text"
print("userInput={}".format(userInput))
Try this: raw_input("Please enter name: Jack" + chr(8)*4)
The ASCII value of backspace
is 08
.
精彩评论