APT komut satırı arayüzü benzeri evet / hayır girişi?


169

APT ( Gelişmiş Paket Aracı ) komut satırı arabiriminin Python'da ne yapmanın kısa bir yolu var mı ?

Yani, paket yöneticisi bir evet / hayır sorusu izlediğinde [Yes/no], bunu komut dosyası kabul eder YES/Y/yes/yveya Enter( Yesbüyük harfle varsayılan olarak varsayılan olarak kabul edilir).

Resmi belgelerde bulduğum tek şey inputve raw_input...

Öykünmek o kadar zor değil biliyorum, ama yeniden yazmak için sinir bozucu: |


15
Python 3'te raw_input()denir input().
Tobu

Yanıtlar:


222

Eğer bahsedildiği gibi, en kolay yolu kullanmaktır raw_input()(veya basitçe input()için Python 3 ). Bunu yapmanın yerleşik bir yolu yoktur. Gönderen 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")

Kullanım örneği:

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

elif choice in valid:Ve muhtemelen bir boolean döndürürdüm.
Ignacio Vazquez-Abrams


24
Aslında, standart kütüphanede bir işlev strtoboolü var: docs.python.org/2/distutils/…
Alexander Artemenko

14
Sadece bir hatırlıyorum: raw_input()adlandırılır input()Python3 içinde
nachouve

Gerçekten süper yararlı! Sadece Python3 raw_input()ile değiştirin input().
Muhammed Haseeb

93

Bunu şu şekilde yaparım:

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

8
raw_input()denir input()Python3 içinde
gizzmole

49

strtoboolPython'un standart kütüphanesinde bir işlev vardır : http://docs.python.org/2/distutils/apiref.html?highlight=distutils.util#distutils.util.strtobool

Kullanıcının girişini kontrol etmek Trueve Falsedeğerine veya değerine dönüştürmek için kullanabilirsiniz .


fmuhtemelen False anlamına gelir ve False == 0bu yüzden mantığı alıyorum. Neden işlev intyerine bir yerine dönecekti boolbana bir gizem.
François Leblanc

@ FrançoisLeblanc Veritabanlarında neden en yaygın olduğu konusunda. Açıkça değilse Falseveya 0(Sıfır). Bool fonksiyonu kullanılarak değerlendirilir şey, başka gerçek olur ve döndürür: 1.
JayRizzo

@JayRizzo Bunu anlıyorum ve her ikisi de birçok açıdan işlevsel olarak benzerler . Ancak bu, singleton karşılaştırmasını kullanamayacağınız anlamına gelir if strtobool(string) is False: do_stuff().
François Leblanc


48

Bunu tek bir seçim için yapmanın çok basit (ama çok karmaşık olmayan) bir yolu:

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

Bunun yanında basit (biraz gelişmiş) bir işlev de yazabilirsiniz:

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

Not: Python 2'de, raw_inputyerine kullanın input.


7
İlk yaklaşımı seviyorum. Kısa ve kolay. Ben şöyle bir şey kullandımresult = raw_input("message").lower() in ('y','yes')
Adrian Shum

24

@Alexander Artemenko tarafından belirtildiği gibi, strtobool kullanarak basit bir çözüm

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

8
sadece merak ediyorum ... neden sys.stdout.writeyerine print?
15'te Anentropik

2
Not strtobool()(benim testlerden) değil bir ihtiyaç lower(). Ancak bu, belgelerinde açık değildir.
Michael - Clay Shirky

15

Bunun bir çok yolla yanıtlandığını biliyorum ve bu OP'nin özel sorusuna cevap vermeyebilir (kriterler listesiyle) ama en yaygın kullanım durumu için yaptığım şey bu ve diğer yanıtlardan çok daha basit:

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

bu python 2 ile çalışmaz - python 3'te raw_inputyeniden adlandırıldı stackoverflow.com/questions/21122540/…input
Brian Tingle

9

Ayrıca komut istemini de kullanabilirsiniz .

Utanmadan README'den alındı:

#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

4
"Default = 'no'" ile kullanırken komut isteminin davranışının oldukça geri olduğuna dikkat edin; 'hayır'ı seçtiğinizde True,' evet'i seçtiğinizde Yanlış değerini döndürür.
rem

7

Fmark'ın cevabını python 2/3 uyumlu daha pythonic ile değiştirdim.

Daha fazla hata işleme içeren bir şeyle ilgileniyorsanız ipython'un yardımcı modülüne bakın

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

Hem Python 2 hem de 3 ile uyumludur, çok okunabilir. Sonunda bu cevabı kullandım.
François Leblanc

4

2.7'de bu çok pitonik değil mi?

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

en azından Evet'in herhangi bir varyasyonunu yakalar.


4

Aynı şeyi python 3.x ile yapmak, orada raw_input()olmayan:

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

Hayır, bu işe yaramıyor. Aslında birden fazla şekilde. Şu anda düzeltmeye çalışıyorum, ama bence bu bitirdikten sonra kabul edilen cevaba çok benzeyecek.
Gormador

Seni anwser @pjm olarak düzenledim. Lütfen gözden geçirmeyi düşünün :-)
Gormador

3

Python 3 için bu işlevi kullanıyorum:

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

Strtobool işlevi bool bir dize dönüştürür. Dize ayrıştırılamazsa, bir ValueError değeri yükseltir.

Python 3'te raw_input girdi olarak yeniden adlandırıldı .


2

'Kabul edilen' şov değişkenindeki seçimlerle çalışabilmek için aşağıdaki kod gibi bir şeyi deneyebilirsiniz:

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

İşte kod ..

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

2

Bir programlama noob olarak, özellikle çok çeşitli evet / hayır sorularını iletebileceğiniz basit bir işleve sahip olmak, kullanıcıyı evet veya hayır seçmeye zorlamaksa, yukarıdaki cevapların bir demetini aşırı derecede karmaşık buldum. Bu sayfayı ve diğerlerini inceledikten ve çeşitli iyi fikirleri ödünç aldıktan sonra aşağıdakilerle sonuçlandım:

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

1
Argüman "cevap" yerine "soru" olarak adlandırılmamalı mı?
AFP_555

1

Buna ne dersin:

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

1

Ne kullanıyorum:

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

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

Ben böyle yapardım.

Çıktı

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

1

İşte benim almak, kullanıcı eylemi teyit etmedi eğer sadece iptal etmek istedim.

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

0

Temizlenmiş bir Python 3 örneği:

# inputExample.py

def confirm_input(question, default="no"):
    """Ask a yes/no question 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", "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: '{}}'".format(default))

    while True:
        print(question + prompt)
        choice = input().lower()
        if default is not None and choice == '':
            return valid[default]
        elif choice in valid:
            return valid[choice]
        else:
            print("Please respond with 'yes' or 'no' "
                             "(or 'y' or 'n').\n")

def main():

    if confirm_input("\nDo you want to continue? "):
        print("You said yes because the function equals true. Continuing.")
    else:
        print("Quitting because the function equals false.")

if __name__ == "__main__":
    main()
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.