python - 如何在 Python 中使大量 if 语句更具可读性
问题描述
我最近练习了 python,我发现自己参与了很多关于一个简单的石头剪刀布游戏的 if 语句,它看起来像这样:我的问题是如何让我的代码更高效、更易于编写和阅读
while True:
player_choice = raw_input("\n1-Rock\n2-Paper\n3-Scissors\n{} choose a number:".format(name))
player_choice = int(player_choice)
if player_choice == 1:
player_choice = Choices.rock
if player_choice == 2:
player_choice = Choices.paper
if player_choice == 3:
player_choice = Choices.scissors
# Getting the cpu choice.
cpu_choice = random.randint(1, 3)
if cpu_choice == 1:
cpu_choice = Choices.rock
if cpu_choice == 2:
cpu_choice = Choices.paper
if cpu_choice == 3:
cpu_choice = Choices.scissors
if player_choice == cpu_choice:
print"\n Its a Tie!\n!"
if player_choice == Choices.paper and cpu_choice == Choices.rock:
print"\n Congratulations!\n{} you won!".format(name)
if player_choice == Choices.scissors and cpu_choice == Choices.paper:
print"\n Congratulations!\n{} you won!".format(name)
if player_choice == Choices.rock and cpu_choice == Choices.scissors:
print"\n Congratulations!\n{} you won!".format(name)
if cpu_choice == Choices.scissors and player_choice == Choices.paper:
print"\n Too bad!\n{} you lost!".format(name)
if cpu_choice == Choices.paper and player_choice == Choices.rock:
print"\n Too bad!\n{} you lost!".format(name)
if cpu_choice == Choices.rock and player_choice == Choices.scissors:
print"\n Too bad!\n{} you lost!".format(name)*
解决方案
您的if
语句可以用字典代替。例如,Choices
可以使用这样的字典将整数映射到特定属性:
choices = {1: Choices.rock, 2: Choices.paper, 3: Choices.scissors}
现在你可以使用
player_choice = choices[player_choice]
和
cpu_choice = random.choice(choices.values())
Choices
从封装的角度来看,处理这种映射实际上应该是对象的责任。如果您要使用实际enum.Enum
对象(需要 Python 3 或安装backport 包) ,enum34
那么您可以使用:
player_choice = Choices(player_choice)
但是根据您定义的方式Choices
,您可以给它一个__call__
基本上使用上述映射的方法来给您相同的结果。
接下来,您可以使用字典来确定获胜者:
# if a player picks the key, and the opponent has picked the value,
# then the player wins.
wins_against = {
Choices.rock: Choices.scissors,
Choices.paper: Choices.rock,
Choices.scissors: Choices.paper,
}
然后确定获胜者:
if player_choice == cpu_choice:
print"\n Its a Tie!\n!"
elif wins_against[player_choice] == cpu_choice:
print"\n Congratulations!\n{} you won!".format(name)
else: # not the same, and not a win, so the player lost
print"\n Too bad!\n{} you lost!".format(name)
但是,该映射也可能是您的Choices
枚举对象的一部分;给它们一个wins_against
属性:
if player_choice == cpu_choice:
print"\n Its a Tie!\n!"
elif player_choice.wins_against == cpu_choice:
print"\n Congratulations!\n{} you won!".format(name)
else:
print"\n Too bad!\n{} you lost!".format(name)
如果您要使用该enum
库,代码可能变为:
from enum import Enum
class Choices(Enum):
rock = 1, 'scissors'
paper = 2, 'rock'
scissors = 3, 'paper'
def __new__(cls, value, win_against):
instance = object.__new__(cls)
instance._value_ = value
instance._win_against = win_against
return instance
@property
def win_against(self):
return type(self)[self._win_against]
while True:
options = '\n'.join(['{}-{}'.format(c.value, c.name) for c in choices])
player_choice = raw_input("\n\n{} choose a number:".format(
options, name))
try:
player_choice = int(player_choice)
player_choice = Choices(player_choice)
except ValueError:
print "Not a valid option, try again"
continue
cpu_choice = random.choice(list(Choices))
if player_choice is cpu_choice:
print"\n Its a Tie!\n!"
elif player_choice.wins_against is cpu_choice:
print"\n Congratulations!\n{} you won!".format(name)
else: # not the same, and not a win, so the player lost
print"\n Too bad!\n{} you lost!".format(name)
推荐阅读
- javascript - Angular,在渲染另一个组件之前等待一个组件完全渲染
- csv - SSIS平面文件连接
- algorithm - Euler's Totient 函数从 1 到 N 的有效总和
- c# - 直接从数据库返回 IEnumerable 或之前使用 ToListAsync
- sql-server - SQL Server,创建存储过程以在日期范围内为每条记录插入无交易天数的行
- javascript - 如何以正确的方式隐藏 Div
- vaadin - Vaadin @DebouceSettings 示例
- wso2is - 将用户管理限制为用户或角色
- c++ - 为什么我不能在这种情况下使用 push_back?
- java - 为什么DataNode不能下载文件?