Je pense que vous éprouvez du mal à comprendre ce qu'est une exception (ou plutôt, un Exception
!) est. Vous les définissez dans le but de comprendre pourquoi votre code a peut-être échoué. Par exemple:
class WrongNumberOfPlayersError(Exception):
pass
Ceci est une Exception
(littéralement, car il hérite de Exception
il peut faire tout un Exception
peut faire) que vous avez défini savoir quand vous avez le mauvais nombre de joueurs! Par conséquent
players = [("Player 1", "S"), ("Player 2", "P"), ("Player 3", "R")]
rps_game_winner(players)
# this should raise an exception, since there are the WRONG NUMBER OF PLAYERS!
-vous gérer ces derniers avec try/except
blocs (appelés try/catch
dans certaines langues) en tant que tels:
while True:
players = get_players() # imagine a function that created this list,
# now you're looping over making a new one each
# time it's wrong
try:
rps_game_winner(players)
except WrongNumberOfPlayersError as e:
# handle the exception somehow. You only make it into this block if
# there are the wrong number of players, and it's already looping forever
# so probably just...
pass
else: # if there are no exceptions
break # get out of the infinite loop!!
Dans votre fonction rps_game_winner
, vous avez la logique suivante:
if len(game) != 2:
raise WrongNumberOfPlayersError("Wrong number of players!")
return print ("A WrongNumberOfPlayers error has occurred. \n\n")
Cette C'est pourquoi je pense que votre compréhension est légèrement erronée. Une fois que vous raise
cette exception, la fonction se termine. Il ne lit jamais la ligne return
(ce qui est probablement pour le mieux puisque vous ne pouvez pas return
une fonction d'impression, c'est juste None
pour des raisons qui sont hors de la portée de cette discussion.) En Python 2, je crois que cela empêcherait votre code de fonctionner. exécuter complètement)
Ceci d'une fonction comme une petite machine qui fonctionne pour vous ("travail" dans ce cas étant une sorte de calcul, ou en cours d'exécution d'un algorithme, etc). Une fois que la machine a fini de fonctionner, le résultat de ce travail est return
. Toutefois, si quelque chose ne va pas, il devrait vous informer que "Hey ce n'est pas le résultat de mon travail, c'est quelque chose de mal," donc raise
s une exception à la place. Essentiellement: vous pouvez soit raise
si quelque chose ne va pas, ou return
si tout va bien. Notez qu'il y a plus de choses erronées que cela (par exemple vous ne pouvez JAMAIS lancer un NoSuchStrategyError
avec votre code actuel) mais que les bases du problème sont dans une mauvaise compréhension des exceptions. Ci-dessous est un morceau de code trop abstrait qui devrait accomplir ce que vous le souhaitez. Gardez à l'esprit que j'ai délibérément obscurci une partie du code de sorte qu'il est inutilisable en tant que copier/coller. En particulier, je suis plutôt fier de ma mise en œuvre de gagner/perdre/dessiner :)
R = 0b001
P = 0b010
S = 0b100
class WrongNumberOfPlayersError(Exception): pass
class NoSuchStrategyError(Exception): pass
class RPSGame(object):
def __init__(self, *players):
try:
self.p1, self.p2 = players
# assume constructed as game('p1','p2')
except Exception:
try: self.p1, self.p2 = players[0]
# assume constructed as game(['p1','p2'])
except Exception:
raise WrongNumberOfPlayersError("Only two players per game")
# no more assumptions, raise that exception
def start(self):
print("{0.name} plays {0.human_choice} || {1.name} plays {1.human_choice}".format(
self.p1, self.p2))
def winner(p1, p2):
global R, P, S
wintable = {R: {R^S: 2, R^P: 1},
P: {P^R: 2, P^S: 1},
S: {S^P: 2, S^R: 1}}
resulttable = ["Draw","Lose","Win"]
return resulttable[wintable[p1.choice].get(p1^p2,0)] + " for {}".format(p1)
return winner(self.p1, self.p2)
class Player(object):
rhyme_to_reason = {R:"Rock", P:"Paper", S:"Scissors"}
def __init__(self, name, choice):
self.name = name
try: choiceU = choice.upper()
except AttributeError:
# choice is R, P, S not "R", "P", "S"
choiceU = choice
if choiceU not in ("R","P","S",R,P,S):
raise NoSuchStrategyError("Must use strategy R, P, or S")
choicetable = {"R":R,"P":P,"S":S}
self.choice = choicetable.get(choiceU,choiceU)
self.human_choice = Player.rhyme_to_reason[self.choice]
def __xor__(self, other):
if not isinstance(other, Player):
raise NotImplementedError("Cannot xor Players with non-Players")
return self.choice^other.choice
def __hash__(self):
return hash((self.name, self.choice))
def __str__(self):
return self.name
if __name__ == "__main__":
import random, itertools
num_players = input("How many players are there? ")
players = [Player(input("Player name: "), input("Choice: ") or random.choice([R,P,S])) for _ in range(int(num_players))]
scoreboard = {player: 0 for player in players}
for pairing in itertools.combinations(players, 2):
game = RPSGame(pairing)
result = game.start()
if result.startswith("W"):
scoreboard[pairing[0]] += 1
elif result.startswith("L"):
scoreboard[pairing[1]] += 1
else:
pass
print(result)
for player, wins in scoreboard.items():
print("{:.<20}{}".format(player,wins))
On dirait que c'est le résultat escompté. Souvenez-vous que vous définissez EXCEPTIONS ici, puis que vous les lancez intentionnellement. Vous DEVRIEZ recevoir un message d'erreur avec un retraçage –
Vous devriez lire [le tutoriel sur les erreurs] (https://docs.python.org/2.7/tutorial/errors.html). Vous devriez également demander à votre professeur si vous trouvez des choses déroutantes; c'est ce qu'ils sont là pour ça. – jonrsharpe