我有一个叫做攻击的功能:
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总是做的事情,还是我做错了什么,因为我不希望这些被调用(对不起,如果我没有使用正确的术语,我有点新)
答案 0 :(得分: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)
这假设你在调用这些函数时仍然想要稍后在上指定播放器和boss 。例如,您可以致电kick(player, boss)
。
使用functools.partial()
并不合适,因为您正在交换boss
和player
个参数;您只需定义slash
变量并按正确的顺序传递boss
和player
个参数:
from functools import partial
slash = partial(attack, 'slash', 1, 2, 5)
kick = partial(attack, 'kick', 1, 1, 1)
调用slash
或kick
会添加任何额外的参数,因此slash(player, boss)
会调用函数,并将这两个参数添加到已经存在的参数上定义
所有这一切都假设您希望能够管理多个玩家和老板。如果你的player
和boss
变量是全局变量(可能只有一个玩家和一个 boss),那么你就是在定义lambda
或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)
让玩家踢老板,你只需拨打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
对象不能用作类的方法,函数对象可以。如果您需要在课程中使用此功能,请使用functools.partialmethod()
object。
答案 1 :(得分:1)
这是functools.partial
的用途。
返回一个新的部分对象,当调用它时,其行为类似于使用位置参数args和keyword arguments关键字调用的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
答案 2 :(得分:0)
将你的功能融入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)
答案 3 :(得分: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)