我在 python 中的函数正在被调用,尽管我只是在定义它

My function in python is being called, even though I'm only defining it

我有一个叫做攻击的函数:

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和玩家做一些实际攻击:

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 经常做的事情,还是我做错了什么,因为我不希望调用这些(抱歉,如果我没有使用正确的术语,我有点新)

将您的函数包装到 lambda 中:

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

或使用partial:

slashp=partial(attack, name="slash",minmultiplier=1,maxmultiplier=2,critchance=5,attacker=player,attackee=boss)

您正在调用这里的函数:

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

您存储的是 return 值,而不是函数。

如果您想存储一些预定义的参数,要么使用另一个函数来包装调用,使用 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() 不太合适,因为您正在交换 bossplayer 参数;您只需定义一个 slash 变量并以正确的顺序传入 bossplayer 参数:

from functools import partial

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

调用 slashkick 添加 任何额外的参数,因此 slash(player, boss) 调用函数时会添加这两个参数到您已经定义的那些。

所有这些都假设您希望能够管理多个玩家和老板。如果你的 playerboss 变量是全局变量(也许只有 one 玩家和 one boss 可以战斗) ,那么您只需在定义 lambdapartial 时传入它们,而不会传入额外的参数。例如:

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()

partial对象和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 对象不能用作 class 上的方法,函数对象可以。如果您需要在 class.

上使用此功能,请使用 functools.partialmethod() object

这就是 functools.partial 的用途。

Return a new partial object which when called will behave like func called with the positional arguments args and keyword arguments keywords. If more arguments are supplied to the call, they are appended to args. If additional keyword arguments are supplied, they extend and override keywords.

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

示例用法:

import functools
slashp = functools.partial("slash",1,2,5,player,boss)
slashp()  # actual call 

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

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)