1

我有一个名为攻击的函数:

def attack(name,minmultiplier,maxmultiplier,critchance,attacker,attackee):
    print(attacker[0],"used",name)
    multiplier=random.randint(minmultiplier,maxmultiplier)
    crit=random.randint(critchance,100)
    if crit==100 and ((attacker[2]*multiplier*2)-attackee[3]) > 0:
        attackee[1]=attackee[1]-((attacker[2]*multiplier*2)-attackee[3])
    elif ((attacker[2]*multiplier)-attackee[3]) > 0:
        attackee[1]=attackee[1]-((attacker[2]*multiplier)-attackee[3])
    else:
        print("You fail to hit",attackee[0])
    print(attackee[0],"'s health after",attacker[0],"'s attack is",attackee[1])

我在这里对老板和玩家进行了一些实际的攻击:

boss=["Greed",1000,10,10,1]
slashp=attack("slash",1,2,5,player,boss)
slashb=attack("slash",1,2,5,boss,player)
kick=attack("kick",1,1,1,player,boss)
aiattacklist=[slashb]
attacknamelist=["slash","kick"]
attackfunclist=[slashp,kick]

即使我只是将这些版本保存为变量,它们仍然被调用:

template used slash
You fail to hit Greed
Greed 's health after template 's attack is 1000
Greed used slash
template 's health after Greed 's attack is 58
template used kick
You fail to hit Greed
Greed 's health after template 's attack is 1000

这是python总是做的事情,还是我做错了什么,因为我不希望这些被调用(对不起,如果我没有使用正确的术语,我有点新)

4

4 回答 4

5

您在这里调用函数:

slashp=attack("slash",1,2,5,player,boss)
slashb=attack("slash",1,2,5,boss,player)
kick=attack("kick",1,1,1,player,boss)

您将返回值存储在那里,而不是函数。

如果你想存储一些预定义的参数,要么使用另一个函数来包装调用,使用 lambda(这基本上是创建函数的一种简化形式),或者使用functools.partial()来预定义一些参数并为它们存储一个新的可调用对象。

使用 lambda 看起来像这样:

shlashp = lambda player, boss: attack("slash", 1, 2, 5, player, boss)
shlashb = lambda player, boss: attack("slash", 1, 2, 5, boss, player)
kick = lambda player, boss: attack("kick", 1, 1, 1, player, boss)

这假设您稍后在调用这些函数时仍想指定玩家和老板。例如,你会打电话kick(player, boss)给 。

在这里使用functools.partial()不太合适,因为您正在交换bossandplayer参数;您只需定义一个变量并以正确的顺序slash传入boss和参数:player

from functools import partial

slash = partial(attack, 'slash', 1, 2, 5)
kick = partial(attack, 'kick', 1, 1, 1)

调用其中一个slashkick添加任何额外的参数,因此slash(player, boss)调用将这两个参数添加到您已经定义的参数的函数。

所有这些都假设您希望能够管理多个玩家和老板。如果你的playerandboss变量是全局变量(也许只有一个玩家和一个老板要战斗),那么你在定义 thelambda或 the时只需传递它们,partial并且你不会传递额外的参数。例如:

slashp = partial(attack, 'slash', 1, 2, 5, player, boss)
slashb = partial(attack, 'slash', 1, 2, 5, boss, player)
kick = partial(attack, 'kick', 1, 1, 1, player, boss)

要让玩家踢boss,你只需跟注kick()

partialobject 和 a的区别在于lambda可以内省partial对象;您可以轻松查看您定义为始终传入的参数:

>>> from functools import partial
>>> def attack(*args): return args
...
>>> demo = partial(attack, 'kick', 1, 2, 5)
>>> demo.args
('kick', 1, 2, 5)
>>> demo()
('kick', 1, 2, 5)
>>> demo('player1', 'boss2')
('kick', 1, 2, 5, 'player1', 'boss2')

partial对象不能用作类的方法,函数对象可以。如果您需要在类上使用此功能,请使用functools.partialmethod()对象。

于 2015-12-17T13:28:04.690 回答
1

这是functools.partial为了什么。

返回一个新的部分对象,当调用它时,它的行为类似于使用位置参数 args 和关键字参数关键字调用的 func。如果为调用提供了更多参数,则将它们附加到 args。如果提供了额外的关键字参数,它们会扩展和覆盖关键字。

https://docs.python.org/2/library/functools.html#functools.partial

示例用法:

import functools
slashp = functools.partial("slash",1,2,5,player,boss)
slashp()  # actual call 
于 2015-12-17T13:33:47.123 回答
0

将你的函数包装成一个 lambda:

slashp=lambda : attack("slash",1,2,5,player,boss)

或使用部分

slashp=partial(attack, name="slash",minmultiplier=1,maxmultiplier=2,critchance=5,attacker=player,attackee=boss)
于 2015-12-17T13:28:00.233 回答
0

类似乎更合适,并在未来提供更多的灵活性

class AttackType(object):
    def __init__(name, minmult, maxmult, crit):
        self.name = name
        self.minmult = minmult
        self.maxmult = maxmult
        self.crit = crit
    def attack(self, attackee, attacker):
        // all your logic here

kick = AttackType("kick", 1, 1, 1)
##... later
kick(player, boss)
于 2015-12-17T13:34:49.080 回答