2010-06-15 5 views
127

Existe-t-il un moyen rapide de réaliser ce que fait l'interface de ligne de commande APT (Advanced Package Tool) en Python?APT interface de ligne de commande-like oui/non entrée?

Je veux dire, lorsque le gestionnaire de paquets demande oui/non suivie [Yes/no], le script accepte YES/Y/yes/y ou Entrez (par défaut Yes par ailleurs suggéré que la lettre majuscule).

La seule chose que je trouve dans les documents officiels est input et raw_input ...

Je sais que ce n'est pas difficile à imiter, mais il est ennuyeux de réécrire: |

+14

En Python 3, 'raw_input()' est appelée [ 'entrée()'] (http://docs.python.org/dev/library/functions.html#input). – Tobu

Répondre

168

Comme vous l'avez mentionné, la manière la plus simple est d'utiliser raw_input(). Il n'y a pas de façon intégrée de le faire. De Recipe 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 <Enter>. 
     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") 

Exemple d'utilisation:

>>> 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 
+0

'choix elif dans valide:' Et je retournerais probablement un booléen. –

+0

Bon choix Ignacio, modification – fmark

+13

En fait, il existe une fonction strtobool dans la bibliothèque standart: http://docs.python.org/2/distutils/apiref.html?highlight=distutils.util#distutils.util.strtobool –

73

que je le ferais de cette façon:

# 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'") 
+0

'raw_input()' est appelé 'input()' dans Python3 – gizzmole

34

Un très simple (mais pas très sophistiqué) façon de le faire pour une le choix unique serait:

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

Vous pouvez aussi écrire une fonction simple (légèrement améliorée) autour de celle-ci:

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

Aime la première approche. Court et facile. J'ai utilisé quelque chose comme 'result = raw_input (" message "). Lower() dans ('y', 'yes')' –

39

Il y a une fonction strtobool dans la bibliothèque standard de Python: http://docs.python.org/2/distutils/apiref.html?highlight=distutils.util#distutils.util.strtobool

Vous pouvez l'utiliser pour vérifier l'entrée de l'utilisateur et le transformer en True ou False valeur.

+0

'strtobool (" f ")' retourne '0' ... –

+0

' f' se dresse probablement pour False, et 'False == 0', donc j'obtiens la logique. Pourquoi la fonction retournerait un 'int' au lieu d'un' bool' est un mystère pour moi cependant. –

1

Que diriez-vous ceci:

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 
2

Vous pouvez essayer quelque chose comme le code ci-dessous pour pouvoir travailler avec des choix de la variable « accepté » montrer ici:

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

Voici le code ..

#!/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 
19

comme mentionné par @Alexander Artemenko, voici une solution simple à l'aide 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 
+7

juste curieux ... pourquoi 'sys.stdout.write' au lieu de' print'? – Anentropic

+1

Notez que 'strtobool()' ne nécessite pas (de mes tests) un 'lower()'. Ce n'est pas explicite dans sa documentation, cependant. – Michael

13

Je sais que cela a été répondu à un tas de façons et cela peut ne pas répondre à la question spécifique de l'OP (avec la liste des critères), mais c'est ce que je l'ai fait pour l'utilisation le plus courant et il est beaucoup plus simple que la d'autres réponses:

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

cela ne fonctionne pas avec python 2 - 'raw_input' a été renommé' input' dans python 3 https: // stackoverflow.com/questions/21122540/input-error-name-name-name-is-not-defined –

1

ce que j'utilise:

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 
7

Vous pouvez également utiliser prompter.

Shamelessly pris du 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 
+3

Attention, le comportement de prompteur est assez en arrière quand vous l'utilisez avec "default = 'no'"; il retournera Vrai quand vous choisissez 'non' et Faux quand vous choisissez 'oui'. – rem

1
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")) 

Voilà comment je le ferais.

Sortie

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

J'ai modifié la réponse de fmark par python 2/3 compatible plus pythonique.

Voir ipython's utility module si vous êtes intéressé par quelque chose avec plus d'erreur de manipulation

# 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) 
+0

Compatible avec les deux Python 2 et 3, très lisible. J'ai fini par utiliser cette réponse. –

1

Voici mon avis sur la question, je voulais simplement faire avorter si l'utilisateur n'a pas affirmé l'action.

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

sur 2.7, est-ce trop non-pythonique?

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

capture toute variation de Yes au moins.

4

Faire la même chose avec 3.x python, où raw_input() n'existe pas:

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") 
+0

Non, cela ne fonctionne pas. De plus d'une manière en fait. J'essaie actuellement de régler le problème, mais je pense que cela ressemblera beaucoup à la réponse acceptée après que j'ai terminé. – Gormador

+0

Je vous ai édité anwser @pjm. S'il vous plaît envisager de l'examiner :-) – Gormador

7

Vous pouvez utiliser la méthode de confirmclick.

import click 

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

Ce imprimera:

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

devrait fonctionner pour Python 2/3 sous Linux, Mac ou Windows.

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

+2

Je ne sais pas pourquoi cette réponse est si faible ... –

+0

'click' est une bombe. Je cherchais quelque chose comme ça depuis des années. – jtpereyda

Questions connexes