【问题标题】:APT command line interface-like yes/no input?APT 命令行界面,类似于是/否输入?
【发布时间】:2026-01-10 05:05:02
【问题描述】:

有没有什么捷径可以实现 Python 中 APT(Advanced Package Tool)命令行界面的功能?

我的意思是,当包管理器提示是/否问题后跟[Yes/no],脚本接受YES/Y/yes/yEnter(默认为Yes,如大写字母所示) .

我在官方文档中找到的唯一内容是inputraw_input...

我知道模仿并不难,但是重写很烦人:|

【问题讨论】:

  • 在 Python 3 中,raw_input() 被称为 input()

标签: python


【解决方案1】:

正如您所提到的,最简单的方法是使用raw_input()(或者简单地使用input() 代替Python 3)。没有内置的方法可以做到这一点。来自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 = 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")

(对于 Python 2,使用 raw_input 而不是 input。) 使用示例:

>>> 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: 我可能会返回一个布尔值。
  • 伊格纳西奥的好选择,正在修改
  • 其实标准库中有一个函数strtobool:docs.python.org/2/distutils/…
  • 请记住:raw_input() 在 Python3 中被称为 input()
  • 确实超级有帮助!对于 Python3,只需将 raw_input() 替换为 input()
【解决方案2】:

我会这样做:

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

【讨论】:

  • raw_input() 在 Python3 中被称为 input()
【解决方案3】:

你可以使用clickconfirm方法。

import click

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

这将打印:

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

应该适用于 Linux、Mac 或 Windows 上的 Python 2/3

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

【讨论】:

    【解决方案4】:

    Python的标准库中有一个函数strtoboolhttp://docs.python.org/2/distutils/apiref.html?highlight=distutils.util#distutils.util.strtobool

    您可以使用它来检查用户的输入并将其转换为TrueFalse 值。

    【讨论】:

    • f 可能代表 False,False == 0,所以我明白了逻辑。不过,为什么函数会返回 int 而不是 bool 对我来说是个谜。
    • @FrançoisLeblanc 关于为什么它在数据库中最常见。如果不是明确的False0(零)。任何使用 bool 函数计算的 else 都变为 true 并将返回:1
    • @JayRizzo 我明白了,他们在大多数方面都是both functionally similar。但这意味着您不能使用单例比较,即if strtobool(string) is False: do_stuff()
    【解决方案5】:

    一个非常简单(但不是很复杂)的方法是:

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

    您还可以围绕此编写一个简单(稍微改进)的函数:

    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
    

    注意:在 Python 2 上,使用 raw_input 而不是 input

    【讨论】:

    • 喜欢第一种方法。简短而容易。我用了result = raw_input("message").lower() in ('y','yes')之类的东西
    【解决方案6】:

    正如@Alexander Artemenko 所说,这是一个使用 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
    

    【讨论】:

    • 只是好奇...为什么sys.stdout.write而不是print
    • 请注意,strtobool()(根据我的测试)不需要lower()。然而,这在其文档中并没有明确说明。
    【解决方案7】:

    我知道这已经得到了很多回答,这可能无法回答 OP 的具体问题(带有标准列表),但这是我为最常见的用例所做的,它比其他回答简单得多:

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

    【讨论】:

    【解决方案8】:

    您也可以使用prompter

    无耻地摘自自述文件:

    #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
    

    【讨论】:

    • 请注意,当您将提示器与“default='no'”一起使用时,它的行为是相当倒退的;选择“否”时返回 True,选择“是”时返回 False。
    【解决方案9】:

    我修改了 fmark 对 python 2/3 compatible more pythonic 的回答。

    如果您对更多错误处理感兴趣,请参阅ipython's utility module

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

    【讨论】:

    • 兼容 Python 2 和 3,可读性强。我最终使用了这个答案。
    【解决方案10】:

    对于 Python 3,我正在使用这个函数:

    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]: ")
            try:
                return bool(strtobool(user_input))
            except ValueError:
                print("Please use y/n or yes/no.\n")
    

    strtobool() 函数将字符串转换为布尔值。如果无法解析字符串,则会引发 ValueError。

    在 Python 3 中,raw_input() 已重命名为 input()

    正如 Geoff 所说,strtobool 实际上返回 0 或 1,因此必须将结果强制转换为 bool。


    这是strtobool的实现,如果你想让特殊的词被识别为true,你可以复制代码并添加你自己的案例。

    def strtobool (val):
        """Convert a string representation of truth to true (1) or false (0).
        True values are 'y', 'yes', 't', 'true', 'on', and '1'; false values
        are 'n', 'no', 'f', 'false', 'off', and '0'.  Raises ValueError if
        'val' is anything else.
        """
        val = val.lower()
        if val in ('y', 'yes', 't', 'true', 'on', '1'):
            return 1
        elif val in ('n', 'no', 'f', 'false', 'off', '0'):
            return 0
        else:
            raise ValueError("invalid truth value %r" % (val,))
    

    【讨论】:

    • 还有一件在实践中可能无关紧要的小事:strtobool,由于某种原因,返回 0 和 1,而不是 FalseTrue。所以如果你需要FalseTrue,请务必致电bool(strtobool(user_input))
    【解决方案11】:

    在 2.7 上,这是不是太非 Pythonic 了?

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

    它至少捕获了 Yes 的任何变化。

    【讨论】:

      【解决方案12】:

      对 python 3.x 执行相同操作,其中 raw_input() 不存在:

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

      【讨论】:

      • 不,这不起作用。实际上不止一种方式。目前正在尝试修复它,但我认为这看起来很像我完成后接受的答案。
      • 我编辑了你的 anwser @pjm 。请考虑审查它:-)
      【解决方案13】:

      您可以尝试以下代码,以便能够使用此处显示的变量“接受”中的选项:

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

      这是代码..

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

      【讨论】:

        【解决方案14】:

        作为一个编程菜鸟,我发现上面的一堆答案过于复杂,特别是如果目标是有一个简单的函数,你可以传递各种是/否问题,迫使用户选择是或否。在浏览了这个页面和其他几个页面,并借鉴了所有各种好主意后,我得出了以下结论:

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

        【讨论】:

        • 不应该将论据称为“问题”而不是“答案”吗?
        【解决方案15】:

        这个怎么样:

        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
        

        【讨论】:

          【解决方案16】:

          这是我用的:

          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
          

          【讨论】:

            【解决方案17】:
            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"))
            

            我就是这样做的。

            输出

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

            【讨论】:

              【解决方案18】:

              这是我的看法,如果用户不确认操作,我只是想中止。

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

              【讨论】:

                【解决方案19】:

                使用 Python 3.8 及更高版本的单行代码:

                while res:= input("When correct, press enter to continue...").lower() not in {'y','yes','Y','YES',''}: pass
                

                【讨论】:

                  【解决方案20】:

                  Python x.x

                  res = True
                  while res:
                      res = input("Please confirm with y/yes...").lower(); res = res not in {'y','yes','Y','YES',''}
                  

                  【讨论】:

                    【解决方案21】:

                    由于预期答案是是或否,在下面的示例中,第一个解决方案是使用函数while 重复问题,第二个解决方案是使用recursion - 是在自己的条款。

                    def yes_or_no(question):
                        while "the answer is invalid":
                            reply = str(input(question+' (y/n): ')).lower().strip()
                            if reply[:1] == 'y':
                                return True
                            if reply[:1] == 'n':
                                return False
                    
                    yes_or_no("Do you know who Novak Djokovic is?")
                    

                    第二种解决方案:

                    def yes_or_no(question):
                        """Simple Yes/No Function."""
                        prompt = f'{question} ? (y/n): '
                        answer = input(prompt).strip().lower()
                        if answer not in ['y', 'n']:
                            print(f'{answer} is invalid, please try again...')
                            return yes_or_no(question)
                        if answer == 'y':
                            return True
                        return False
                    
                    def main():
                        """Run main function."""
                        answer = yes_or_no("Do you know who Novak Djokovic is?")
                        print(f'you answer was: {answer}')
                    
                    
                    if __name__ == '__main__':
                        main()
                    

                    【讨论】:

                      【解决方案22】:

                      我以前做的是……

                      question = 'Will the apple fall?'
                      print(question)
                      answer = int(input("Pls enter the answer: "
                      if answer == "y",
                      print('Well done')
                      print(answer)
                      

                      【讨论】: