Python 3.x 使用if语句终止for循环
我不太确定这个问题怎么说,所以我会继续解释我的具体目标 我正在尝试为文本冒险的用户输入函数实现一个“eat”选项。我希望它检查动词是否为“eat”,检查物品是否在玩家的库存中,检查物品是否可消费,然后-我的目标-显示玩家吃了它(并且只显示一次,见下文)。“eat”选项到目前为止还没有任何功能,我只是测试print语句 我完全知道下面的代码不是处理用户输入的最有效的方法(我仍然在调整处理意外输入的方法),所以我100%接受批评。这只是我最初处理它的方式,我想试着让它发挥作用。我还有几个动词('go','look','take',等等)可以用,我只是对'eat'有很多麻烦Python 3.x 使用if语句终止for循环,python-3.x,Python 3.x,我不太确定这个问题怎么说,所以我会继续解释我的具体目标 我正在尝试为文本冒险的用户输入函数实现一个“eat”选项。我希望它检查动词是否为“eat”,检查物品是否在玩家的库存中,检查物品是否可消费,然后-我的目标-显示玩家吃了它(并且只显示一次,见下文)。“eat”选项到目前为止还没有任何功能,我只是测试print语句 我完全知道下面的代码不是处理用户输入的最有效的方法(我仍然在调整处理意外输入的方法),所以我100%接受批评。这只是我最初处理它的方式,我想试着让它发挥作用。我还有几个动词('go
def user_input(self):
player = Player()
while True:
user_input = input("> ").lower()
words = user_input.split(" ")
wordlist = list(words)
verb = wordlist[0]
if len(wordlist) == 2:
noun = wordlist[1]
if noun not in items:
print("Somehow '{}' isn't the right word.".format(noun))
continue
else:
pass
# The above works fine because I don't have
# an issue with any of the other verbs regarding
# that bit of code.
# There's more code between these blocks to:
# handle if the user enters a noun that is > 1 word,
# define a few more verbs,
# then,
if verb == "eat":
for item in player.inventory:
if item.name == noun:
if isinstance(item, Consumable):
print("You eat the {}.".format(noun))
break
else:
print("You can't eat that!")
break
else:
print("You don't have '{}'.".format(noun))
我必须使用for循环(至少,我想我必须这样做),因为我在迭代一个包含对象的列表,而不是字符串,所以我不能只使用for循环
if noun in player.inventory:
(尽管如此,我还是尝试了一百万次,但我花了很长时间才想出解决这个问题的办法)。下面是我对上述代码的具体示例:
class Fists(Weapons):
def __init__(self):
self.name = "fists"
# more instance variables for Fists()
class LeatherWallet(Classy):
def __init__(self):
self.name = "leather wallet"
# more ...
class Pizza(Consumable):
def __init__(self):
self.name = "pizza"
# more ...
class Player():
def __init__(self):
self.inventory = [Fists(), LeatherWallet(), Pizza()]
# other stuff
*吃拳头
You can't eat that!
*吃皮夹
You don't have 'leather wallet'.
You can't eat that!
*吃披萨
You don't have 'pizza'.
You don't have 'pizza'.
You eat the pizza.
从外观上看,它必须是一个简单的修复,因为当它在列表上迭代时,很清楚发生了什么。我只是不知道如何(或者如果可以的话)让for循环先检查条件,然后再打印。冒着听上去愚蠢的危险,我向你们所有人求助
谢谢,如果我能把这个问题/我的目标说得更清楚,请告诉我
编辑:
试图在开头的段落中把目标说得更清楚一些。你没有说你想要的输出是什么,但我最好的猜测是你不想说“你没有X”不止一次 一种方法是使用一个标志,初始化为false,在找到该项时设置为true。当您退出循环时,标志将告诉您是否找到了它 大概是这样的:
if verb == "eat":
found = false
for item in player.inventory:
if item.name == noun:
found = true
if isinstance(item, Consumable):
print("You eat the {}.".format(noun))
break
else:
print("You can't eat that!")
break
if !found:
print("You don't have '{}'.".format(noun))
for
循环有else
子句,如果循环没有中断退出,这些子句将运行。其思想是,循环正在寻找一个项目,当它找到它时就会中断,else
子句处理默认情况,即您找不到要查找的内容。循环结束后,循环中使用的变量仍然有效,因此可以在下一位代码中使用找到的(或默认的)变量
在您的情况下,如果将最后一个else子句移出一个级别,则只有在找不到该项时,它才会运行。在示例输出中,将不再打印两行“you not have'pizza1”
for item in player.inventory:
if item.name == noun:
if isinstance(item, Consumable):
print("You eat the {}.".format(noun))
break
else:
print("You can't eat that!")
break
else:
print("You don't have '{}'.".format(noun))
item = None # <-- you can give a default value if you want to
# use the variable later
然后,for循环被替换为
try:
item = player.inventory[noun]
if isinstance(item, Consumable):
print("You eat the {}.".format(noun))
else:
print("You can't eat that!")
except KeyError:
print("You don't have '{}'.".format(noun))
所以,另一种方法就是让它发挥作用,对吗
if noun in player.inventory:
...
你(至少)有两种方法
列表理解
第一个简单的方法是使用:
就这样
自定义类
第二个是创建一个Inventory
类,该类继承并重写该方法,以便您可以根据需要对它们进行比较
比如:
class Inventory(list):
def __contains__(self, item):
"""
Override `list.__contains__`.
"""
# First, check whether `item` is in the inventory.
#
# This is what a normal `list` would do.
if list.__contains__(self, item):
return True
# If we couldn't find the item in the list searching
# the "normal" way, then try comparing comparing it
# against the `name` attribute of the items in our
# inventory.
for inventory_item in self:
# Ensure we can do `inventory_item.name` so we don't get
# an AttributeError.
if 'name' not in dir(inventory_item):
continue
if inventory_item.name == item:
return True
return False
然后您可以实例化您的库存,如:
self.inventory = Inventory([Fists(), LeatherWallet(), Pizza()])
请记住,Inventory
继承自list
,因此如果您可以执行list(x)
,那么您也应该能够执行Inventory(x)
,并获得非常类似的结果(取决于您在类中重写的程度)
您还可以发挥创意,使所有项目从
Item
类继承,在该类中定义方法并使Pizza()==“Pizza”
简化库存比较。这非常有效!这么简单的一个加法。非常感谢。我不知道for…else机制。酷。
class Inventory(list):
def __contains__(self, item):
"""
Override `list.__contains__`.
"""
# First, check whether `item` is in the inventory.
#
# This is what a normal `list` would do.
if list.__contains__(self, item):
return True
# If we couldn't find the item in the list searching
# the "normal" way, then try comparing comparing it
# against the `name` attribute of the items in our
# inventory.
for inventory_item in self:
# Ensure we can do `inventory_item.name` so we don't get
# an AttributeError.
if 'name' not in dir(inventory_item):
continue
if inventory_item.name == item:
return True
return False
self.inventory = Inventory([Fists(), LeatherWallet(), Pizza()])