【问题标题】:Python CTRL-C exit without traceback?Python CTRL-C 退出没有回溯?
【发布时间】:2012-09-10 01:55:35
【问题描述】:

为学习目的构建一个简单的“石头、剪子、布”的 Python 游戏。

我在这里阅读了其他一些关于退出 Python 而没有回溯的帖子。我正在尝试实现它,但仍然得到追溯!一些 Python 奇才可以指出这个 Python 假人有什么问题吗?这个想法是单击 RETURN(或键入“yes”或“y”将使程序再次运行 play(),但按 CTRL-C 将关闭它而不会回溯。我使用的是 Python 2.7。

    # modules
    import sys, traceback
    from random import choice

    #set up our lists
    ROCK, PAPER, SCISSORS = 1, 2, 3
    names = 'ROCK', 'PAPER', 'SCISSORS'

    #Define a function for who beats who?
    def beats(a, b):
        return (a,b) in ((PAPER, ROCK), (SCISSORS, PAPER), (ROCK, SCISSORS))

    def play():
        print "Please select: "
        print "1 Rock"
        print "2 Paper"
        print "3 Scissors"
        # player choose Rock, Paper or Scissors
        player_choice = int(input ("Choose from 1-3: "))
        # assigns the CPU variable a random CHOICE from a list.
        cpu_choice = choice((ROCK, PAPER, SCISSORS))

        if cpu_choice != player_choice:
            if beats(player_choice, cpu_choice):
                print "You chose %r, and the CPU chose %r." % (names[player_choice - 1], names[cpu_choice - 1])
                print "You win, yay!!"
            else:
                print "You chose %r, and the CPU chose %r." % (names[player_choice - 1], names[cpu_choice - 1])
                print "You lose. Yuck!"
        else:
            print "You chose %r, and the CPU chose %r." % (names[player_choice - 1], names[cpu_choice - 1])
            print "It's a tie!"

        print "Do you want to play again? Click RETURN to play again, or CTRL-C to exit!"

        next = raw_input("> ")

        # THIS IS WHAT I'M WORKING ON - NEED TO REMOVE TRACEBACK!
        if next == "yes" or "y":
            try:
                play()
            except KeyboardInterrupt:
                print "Goodbye!"
            except Exception:
                traceback.print_exc(file=sys.stdout)
            sys.exit(0)
        elif next == None:
            play()
        else:
            sys.exit(0)

# initiate play() !
play()

【问题讨论】:

  • 你能告诉我们你的追溯吗?
  • 我在这里第一次看到这种没有回溯的退出代码:stackoverflow.com/questions/1187970/…,但不同的是现在我试图在 if-elif-else 语句中使用它...跨度>
  • 你能把你的输出粘贴到这里吗?我无法重现。此外,您的代码不会像您的问题中复制的那样运行。你需要定义play()next
  • 另外,exit(0) 应该是sys.exit(0)
  • 小心你的 if 语句。 a = 'n'; bool(a == 'yes' or 'y') 返回True

标签: python python-2.7 exit traceback


【解决方案1】:

尝试重构你的主循环;更多类似的东西:

try:
    while (play()):
        pass
except KeyboardInterrupt:
    sys.exit(0)

play 看起来像:

def play():
    _do_play() # code for the actual game

    play_again = raw_input('play again? ')
    return play_again.strip().lower() in ("yes", "y")

【讨论】:

    【解决方案2】:

    您调用了两次play(),因此您需要将两种情况放在try/except 块中:

    if next in ("yes", "y"):
        try:
            play()
        except KeyboardInterrupt:
            print "Goodbye!"
        except Exception:
            traceback.print_exc(file=sys.stdout)
        sys.exit(0)
    elif next is None:
        try:
            play()
        except KeyboardInterrupt:
            print "Goodbye!"
        except Exception:
            traceback.print_exc(file=sys.stdout)
            sys.exit(0)
    else:
        sys.exit(0)
    

    我已经纠正了另外两个问题,最好在 python 中用is 测试None,而你的第一个if 测试不起作用,因为next == "yes" or "y" 被解释为next == "yes""y" 分开,中间有or"y" 始终被视为 True,因此您永远不会来到代码中的其他分支。

    请注意,我怀疑上面的代码可以进一步简化,但您根本没有向我们展示您的 play() 函数,所以您让我们猜测您要做什么。

    【讨论】:

    • 一个价格三个答案!
    • @KarlKnechtel:是的,改写了一点。
    • 有什么好的理由不将None 放入('y','yes') 元组并避免重复代码?我意识到这将再次带我们回到测试nxt == None 而不是nxt is None,但我认为在这里保存重复的代码是值得的(因为nxt 不太可能是带有自定义@ 的对象987654340@)
    • @Martijn Pieters:能在众多真正的专家中学习 Python,我感到很幸运。也感谢您指出 next== "yes" 或 "y" 中的 "y" 是多余的 - 这是我的新手错误。
    • 而且,我想,当我们讨论提示/代码建议的主题时,我们可能想建议 OP 也不要影响内置 next ...
    【解决方案3】:

    一个问题是您需要将raw_input 语句包含在try except KeyboardInterrupt 子句以及实际的play 函数中。例如

    try:
       nxt = raw_input('>')
       if nxt.lower().startswith('y') or (nxt.strip() == ''):
          play()
       else:
          sys.exit(0)
    except KeyboardInterrupt:
       sys.exit(0)
    except Exception:
       traceback.print_exc(file=sys.stdout)
    

    【讨论】:

    • @MartijnPieters -- 我仍然很难解析该回溯。 (令人惊讶的是,这些换行符有多大帮助)......最终,我们是否可以同意某个地方的某些 raw_input 没有包含在他的 try/except 中?
    • raw_input 他的 play() 函数中(“第 44 行,正在运行”raw_input 部分之前)。但是是的,raw_input 抛出异常,但没有被捕获。
    • @MartijnPieters:是的,我更新了问题中的代码以反映整个程序。我只是在我的第一个小时左右看这个,所以它真的很粗糙。感谢您的宝贵建议和见解。
    猜你喜欢
    • 2010-11-14
    • 1970-01-01
    • 1970-01-01
    • 2016-02-17
    • 1970-01-01
    相关资源
    最近更新 更多