我需要将不同数量的船只传递给代码,但是当我在hit_or_miss函数中时仍然可以使用他们的名字。有没有办法传递任意数量的参数(作为对象),但仍然专门按名称访问它们?
hit_or_miss(ship_1, ship_2, ship_3)
def hit_or_miss(*args):
# Everything from here on should go in your for loop!
# Be sure to indent four spaces!
ships_sunk = 0
for turn in range(4):
print "Turn", turn + 1
guess_row = int(raw_input("Guess Row:"))
guess_col = int(raw_input("Guess Col:"))
guess_loc = ((guess_row,guess_col))
# A correct guess congratulates and exits the game
if guess_loc in ship_1.location or \
guess_loc in ship_2.location or \
guess_loc in ship_3.location:
print "Congratulations! You sunk a battleship!"
ships_sunk += 1
board[guess_row - 1][guess_col - 1] = "H"
答案 0 :(得分:1)
你可以尝试用你的args上的循环替换你的if
语句。
hit_or_miss(ship_1, ship_2, ship_3)
def hit_or_miss(*args):
ships_sunk = 0
for turn in range(4):
print "Turn", turn + 1
guess_row = int(raw_input("Guess Row:"))
guess_col = int(raw_input("Guess Col:"))
guess_loc = ((guess_row,guess_col))
# A correct guess congratulates and exits the game
# Try something like this
for ship in args:
if guess_loc in ship.location:
print("Congratulations! You sunk a {}".format(ship.ship_type))
ships_sunk +=1
board[guess_row - 1][guess_col - 1] = "H"
我假设args是你传入的类,你可以添加ship_type属性。 (我没有对此进行测试,因此您可能需要对其进行调整。)
请注意,在函数内部,* args现在是可迭代的args。只要在函数定义中包含*
,名称args就是任意的。您可以使用def hit_or_miss(*args)
然后循环ships
。这允许您循环传递到函数中的所有内容。
您可能也对**kwargs
感兴趣,但我认为这不是您的功能所必需的。
答案 1 :(得分:0)
你可以使用kwargs。它们基本上将您的键值参数转换为您可以在函数中访问的字典:
def hit_or_miss(**kwargs):
print kwargs
hit_or_miss(ship1=ship1, ship2=ship2)
>>> {'ship2': *yourshipobject*, 'ship1': *yourshipobject*}
答案 2 :(得分:0)
没有检查上部堆栈框架就无法做到这一点,检查堆栈框架通常是一个坏主意。
更好的方法是将一个属性(可能是ship._name)注入该类,然后将其映射到:
ships = {ship._name: ship for ship in args}
然后您可以将其作为普通字典进行访问:
ships["ship1"].location
或迭代它们:
for ship in ships.values():
print(ship.location)
使用**kwargs
仍然需要您传递名称,我相信在这种情况下它不会像注射一样模块化。
答案 3 :(得分:0)
1)为什么你不能使用船只清单?
def hit_or_miss(ships):
for ship in ships: pass
hit_or_miss([ship1, ship2, ship3])
2)或者使用可变数量的参数声明hit_or_miss
?
def hit_or_miss(*ships):
for ship in ships: pass
hit_or_miss(ship1, ship2, ship3)
3)如果您需要命名参数,请将字典传递给函数
def hit_or_miss(**ships):
for ship in ships: pass
# ships are accessed with ships['ship1'] etc.
hit_or_miss(ship1=Ship(...), ship2=Ship(...))
4)不要这样做,但你可以通过动态评估新变量来获得所需的行为。这使您的代码难以阅读和调试,并可能暴露安全漏洞。除非你有充分的理由这样做,否则请使用前三个中的一个。
def hit_or_miss(ships):
for i in range(len(ships)):
exec(('ship{} = ships[{}]').format(i, i))
# we can access `ship1` here now.
hit_or_miss([ship1, ship2, ship3])
答案 4 :(得分:0)
我认为你误解了“任意”这个词。这意味着传递给函数的船舶数量可变,而不仅仅是3。
如果你的功能应该只按照名称引用3艘船,则该功能应该采用3个参数:
def hit_or_miss(ship1, ship2, ship3):
这不会允许可变数量的船舶,但会比您当前的版本效果更好!
当您编写函数时,您正在使用全局变量ship_1, ship_2, ship_3
,所以如果我调用您的函数:
hit_or_miss(a,b,c)
您的函数会查找名为ship_1, ship_2, ship_3
的全局定义变量,完全忽略参数!
同样,您如何期望按名称引用可变数量的船舶?如果你把这个函数称为:
hit_or_miss(ship_a, ship_b) #only 2 arguments, no ship_3
hit_or_miss(s1, s2, s3, s4) #4 arguments, how do you name the fourth?
所以没有办法取任意数量的参数并按名称引用所有参数。但是,您只在这一条件下使用船只:
if guess_loc in ship_1.location or \
guess_loc in ship_2.location or \
guess_loc in ship_3.location:
看起来很像你想检查条件是否为any
,所以具有可变数量的船只的等价物将是:
if any((guess_loc in ship.location) for ship in args):
这将检查参数中传递的any
船只是否符合条件。