python ctrl-c退出而不进行跟踪?

Python CTRL-C exit without traceback?

建立一个简单的Python游戏"石头,纸,剪刀"的学习目的。

我在这里读过其他一些关于退出没有回溯的python的文章。我正在尝试实现它,但仍然有一个回溯!一些python wiz能指出这个python假人有什么问题吗?其想法是点击返回(或输入"是"或"Y")将使程序再次运行play(),但点击ctrl-c将关闭它而不进行回溯。我使用的是python2.7。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
    # 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()


试着重组你的主循环;更多的事情是:

1
2
3
4
5
try:
    while (play()):
        pass
except KeyboardInterrupt:
    sys.exit(0)

play看起来:

1
2
3
4
5
def play():
    _do_play() # code for the actual game

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


你给play()打了两次电话,所以你需要把这两种情况都放在try/except块:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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()函数,所以您让我们来猜测您要做什么。


一个问题是,您需要将您的raw_input语句附在tryexcept KeyboardInterrupt子句中,以及实际的play函数中。例如

1
2
3
4
5
6
7
8
9
10
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)