¿Interfaz de línea de comando APT como si / no entrada?

¿Hay alguna forma corta de lograr lo que hace la interfaz de línea de comandos de APT ( Advanced Package Tool ) en Python?

Quiero decir, cuando el administrador de paquetes hace una pregunta de sí / no seguida de [Yes/no] , la secuencia de comandos acepta YES/Y/yes/y o Ingresa (de manera predeterminada, como se indica en la letra mayúscula).

Lo único que encuentro en los documentos oficiales es input y raw_input

Sé que no es tan difícil de emular, pero es molesto reescribir: |

Como mencionaste, la forma más fácil es usar raw_input() (o simplemente input() para Python 3 ). No hay una forma integrada de hacer esto. De la receta 577058 :

 import sys def query_yes_no(question, default="yes"): """Ask a yes/no question via raw_input() and return their answer. "question" is a string that is presented to the user. "default" is the presumed answer if the user just hits . It must be "yes" (the default), "no" or None (meaning an answer is required of the user). The "answer" return value is True for "yes" or False for "no". """ valid = {"yes": True, "y": True, "ye": True, "no": False, "n": False} if default is None: prompt = " [y/n] " elif default == "yes": prompt = " [Y/n] " elif default == "no": prompt = " [y/N] " else: raise ValueError("invalid default answer: '%s'" % default) while True: sys.stdout.write(question + prompt) choice = raw_input().lower() if default is not None and choice == '': return valid[default] elif choice in valid: return valid[choice] else: sys.stdout.write("Please respond with 'yes' or 'no' " "(or 'y' or 'n').\n") 

Ejemplo de uso:

 >>> query_yes_no("Is cabbage yummier than cauliflower?") Is cabbage yummier than cauliflower? [Y/n] oops Please respond with 'yes' or 'no' (or 'y' or 'n'). Is cabbage yummier than cauliflower? [Y/n] [ENTER] >>> True >>> query_yes_no("Is cabbage yummier than cauliflower?", None) Is cabbage yummier than cauliflower? [y/n] [ENTER] Please respond with 'yes' or 'no' (or 'y' or 'n'). Is cabbage yummier than cauliflower? [y/n] y >>> True 

Lo haría de esta manera:

 # raw_input returns the empty string for "enter" yes = {'yes','y', 'ye', ''} no = {'no','n'} choice = raw_input().lower() if choice in yes: return True elif choice in no: return False else: sys.stdout.write("Please respond with 'yes' or 'no'") 

Hay una función strtobool en la biblioteca estándar de Python: http://docs.python.org/2/distutils/apiref.html?highlight=distutils.util#distutils.util.strtobool

Puede usarlo para verificar la entrada del usuario y transformarlo en valor True o False .

Una forma muy simple (pero no muy sofisticada) de hacer esto para una sola opción sería:

 msg = 'Shall I?' shall = input("%s (y/N) " % msg).lower() == 'y' 

También puedes escribir una función simple (ligeramente mejorada) alrededor de esto:

 def yn_choice(message, default='y'): choices = 'Y/n' if default.lower() in ('y', 'yes') else 'y/N' choice = input("%s (%s) " % (message, choices)) values = ('y', 'yes', '') if choices == 'Y/n' else ('y', 'yes') return choice.strip().lower() in values 

Nota: En Python 2, use raw_input lugar de input .

Puede utilizar el método de confirm clic .

 import click if click.confirm('Do you want to continue?', default=True): print('Do something') 

Esto imprimirá:

 $ Do you want to continue? [Y/n]: 

Debería funcionar para Python 2/3 en Linux, Mac o Windows.

Docs: http://click.pocoo.org/5/prompts/#confirmation-prompts

Como lo mencionó @Alexander Artemenko, aquí hay una solución simple usando strtobool

 from distutils.util import strtobool def user_yes_no_query(question): sys.stdout.write('%s [y/n]\n' % question) while True: try: return strtobool(raw_input().lower()) except ValueError: sys.stdout.write('Please respond with \'y\' or \'n\'.\n') #usage >>> user_yes_no_query('Do you like cheese?') Do you like cheese? [y/n] Only on tuesdays Please respond with 'y' or 'n'. ok Please respond with 'y' or 'n'. y >>> True 

Sé que esto se ha respondido de muchas maneras y puede que no responda a la pregunta específica de OP (con la lista de criterios), pero esto es lo que hice para el caso de uso más común y es mucho más simple que las otras respuestas:

 answer = input('Please indicate approval: [y/n]') if not answer or answer[0].lower() != 'y': print('You did not indicate approval') exit(1) 

También puedes usar el indicador .

Tomado descaradamente de la README:

 #pip install prompter from prompter import yesno >>> yesno('Really?') Really? [Y/n] True >>> yesno('Really?') Really? [Y/n] no False >>> yesno('Really?', default='no') Really? [y/N] True 

He modificado la respuesta de fmark a python 2/3 compatible más pythonic.

Vea el módulo de utilidad de ipython si está interesado en algo con más manejo de errores

 # PY2/3 compatibility from __future__ import print_function # You could use the six package for this try: input_ = raw_input except NameError: input_ = input def query_yes_no(question, default=True): """Ask a yes/no question via standard input and return the answer. If invalid input is given, the user will be asked until they acutally give valid input. Args: question(str): A question that is presented to the user. default(bool|None): The default value when enter is pressed with no value. When None, there is no default value and the query will loop. Returns: A bool indicating whether user has entered yes or no. Side Effects: Blocks program execution until valid input(y/n) is given. """ yes_list = ["yes", "y"] no_list = ["no", "n"] default_dict = { # default => prompt default string None: "[y/n]", True: "[Y/n]", False: "[y/N]", } default_str = default_dict[default] prompt_str = "%s %s " % (question, default_str) while True: choice = input_(prompt_str).lower() if not choice and default is not None: return default if choice in yes_list: return True if choice in no_list: return False notification_str = "Please respond with 'y' or 'n'" print(notification_str) 

en 2.7, ¿es esto también no pythonico?

 if raw_input('your prompt').lower()[0]=='y': your code here else: alternate code here 

Captura cualquier variación de Sí al menos.

Haciendo lo mismo con python 3.x, donde raw_input() no existe:

 def ask(question, default = None): hasDefault = default is not None prompt = (question + " [" + ["y", "Y"][hasDefault and default] + "/" + ["n", "N"][hasDefault and not default] + "] ") while True: sys.stdout.write(prompt) choice = input().strip().lower() if choice == '': if default is not None: return default else: if "yes".startswith(choice): return True if "no".startswith(choice): return False sys.stdout.write("Please respond with 'yes' or 'no' " "(or 'y' or 'n').\n") 

Puede intentar algo como el código a continuación para poder trabajar con opciones de la variable ‘aceptada’ que se muestra aquí:

 print( 'accepted: {}'.format(accepted) ) # accepted: {'yes': ['', 'Yes', 'yes', 'YES', 'y', 'Y'], 'no': ['No', 'no', 'NO', 'n', 'N']} 

Aquí está el código ..

 #!/usr/bin/python3 def makeChoi(yeh, neh): accept = {} # for w in words: accept['yes'] = [ '', yeh, yeh.lower(), yeh.upper(), yeh.lower()[0], yeh.upper()[0] ] accept['no'] = [ neh, neh.lower(), neh.upper(), neh.lower()[0], neh.upper()[0] ] return accept accepted = makeChoi('Yes', 'No') def doYeh(): print('Yeh! Let\'s do it.') def doNeh(): print('Neh! Let\'s not do it.') choi = None while not choi: choi = input( 'Please choose: Y/n? ' ) if choi in accepted['yes']: choi = True doYeh() elif choi in accepted['no']: choi = True doNeh() else: print('Your choice was "{}". Please use an accepted input value ..'.format(choi)) print( accepted ) choi = None 

Como noob de progtwigción, encontré un grupo de respuestas anteriores demasiado complejas, especialmente si el objective es tener una función simple a la que pueda pasar varias preguntas de sí / no, lo que obliga al usuario a seleccionar sí o no. Después de recorrer esta página y varias otras, y de tomar prestadas todas las buenas ideas, terminé con lo siguiente:

 def yes_no(question_to_be_answered): while True: choice = input(question_to_be_answered).lower() if choice[:1] == 'y': return True elif choice[:1] == 'n': return False else: print("Please respond with 'Yes' or 'No'\n") #See it in Practice below musical_taste = yes_no('Do you like Pine Coladas?') if musical_taste == True: print('and getting caught in the rain') elif musical_taste == False: print('You clearly have no taste in music') 

Para Python 3, estoy usando esta función:

 def user_prompt(question: str) -> bool: """ Prompt the yes/no-*question* to the user. """ from distutils.util import strtobool while True: user_input = input(question + " [y/n]: ").lower() try: result = strtobool(user_input) return result except ValueError: print("Please use y/n or yes/no.\n") 

La función strtobool convierte una cadena en un bool. Si la cadena no se puede analizar, generará un ValueError.

En Python 3, raw_input ha sido renombrado a entrada .

Qué tal esto:

 def yes(prompt = 'Please enter Yes/No: '): while True: try: i = raw_input(prompt) except KeyboardInterrupt: return False if i.lower() in ('yes','y'): return True elif i.lower() in ('no','n'): return False 

Esto es lo que uso:

 import sys # cs = case sensitive # ys = whatever you want to be "yes" - string or tuple of strings # prompt('promptString') == 1: # only y # prompt('promptString',cs = 0) == 1: # y or Y # prompt('promptString','Yes') == 1: # only Yes # prompt('promptString',('y','yes')) == 1: # only y or yes # prompt('promptString',('Y','Yes')) == 1: # only Y or Yes # prompt('promptString',('y','yes'),0) == 1: # Yes, YES, yes, y, Y etc. def prompt(ps,ys='y',cs=1): sys.stdout.write(ps) ii = raw_input() if cs == 0: ii = ii.lower() if type(ys) == tuple: for accept in ys: if cs == 0: accept = accept.lower() if ii == accept: return True else: if ii == ys: return True return False 
 def question(question, answers): acceptable = False while not acceptable: print(question + "specify '%s' or '%s'") % answers answer = raw_input() if answer.lower() == answers[0].lower() or answers[0].lower(): print('Answer == %s') % answer acceptable = True return answer raining = question("Is it raining today?", ("Y", "N")) 

Así es como lo haría yo.

Salida

 Is it raining today? Specify 'Y' or 'N' > Y answer = 'Y' 

Aquí está mi opinión, simplemente quise abortar si el usuario no afirmó la acción.

 import distutils if unsafe_case: print('Proceed with potentially unsafe thing? [y/n]') while True: try: verify = distutils.util.strtobool(raw_input()) if not verify: raise SystemExit # Abort on user reject break except ValueError as err: print('Please enter \'yes\' or \'no\'') # Try again print('Continuing ...') do_unsafe_thing()