python 如何使用字典存储具有不同参数要求的多个函数

t1rydlwq  于 2023-02-18  发布在  Python
关注(0)|答案(2)|浏览(158)

我正在尝试建立一个字典,看起来像这样(一个有趣的项目):

_cardLibrary = {
    
    
    1: {'name': 'Strike',
        'cost': 1,
        'type': 'attack',
        'rarity': 'common',
        'action': [deal_damage]
       },
    
    2: {'name': 'Defend',
        'cost': 1,
        'type': 'skill',
        'rarity': 'common',
        'action': [give_block]
       },
    
    3: {'name': 'Bash',
        'cost': 2,
        'type': 'attack',
        'rarity': 'common',
        'action': 
            [deal_damage,
             apply_status] 

       }

}

我想构建一个函数use(i),它接受特定的卡片并执行存储在action中的代码,正如你在第三个元素中看到的,action应该能够包含多个函数,每个函数都需要特定的参数。
例如,deal_damage需要3个参数。应用状态需要4个参数。
deal_damage(施法者,目标,基础伤害)apply_status(施法者,目标,状态,强度)
有没有办法创建一个函数来调用存储在每张特定卡中的所有函数?
我还需要一些方法来传递实际的参数给每一个函数...有些参数可以是常数值。比如,对于这张特定的卡片,状态总是1,强度是1。然而,目标和施法者确实需要在初始使用(施法者,目标)函数中定义...
到目前为止,我已经尝试过迭代每一个函数,然而,这给我留下了一个问题,那就是不能将具体的参数传递给每个函数...
我也试过这个链接:Python: iterate through functions with different arguments
但由于某种原因我无法让代码工作
如果这根本不起作用,我考虑过让每一张卡本身都有一个功能的可能性,然而,这是有问题的,因为其他原因...特别是关于可扩展性。
我该怎么做呢?
谢谢大家

jckbn6z7

jckbn6z71#

你可以使用functools.partial为每个函数预定义一些参数,然后,当你需要调用这些函数时,你只需要指定castertarget参数:

from functools import partial

def deal_damage(caster, target, basedamage):
    print(f"{caster} dealt {basedamage} damage to {target}")

def give_block(caster, target, defense):
    print(f"{caster} blocked {defense} damage from {target}")

def apply_status(caster, target, status, intensity):
    print(f"{caster} applied {intensity}x{status} to {target}")

_cardLibrary = {
    "strike": {'name': 'Strike',
        'cost': 1,
        'type': 'attack',
        'rarity': 'common',
        'actions': [partial(deal_damage, basedamage=10)]
       },
    
    "defend": {'name': 'Defend',
        'cost': 1,
        'type': 'skill',
        'rarity': 'common',
        'actions': [partial(give_block, defense=5)]
       },
    
    "bash": {'name': 'Bash',
        'cost': 2,
        'type': 'attack',
        'rarity': 'common',
        'actions': 
            [partial(deal_damage, basedamage=5),
             partial(apply_status, status='stun', intensity=5)] 

       }
}

注意,我将字典的键改为字符串,将每张卡片中的'action'键改为'actions',因为每张卡片可以有多个操作。
然后,在游戏循环中,可以像调用常规函数一样调用这些partial对象:

while True:
    print(f"You have {len(_cardLibrary)} cards: ")
    print(", ".join(_cardLibrary))
    u_in = input("What would you like to do? (or quit) ").lower()
    if u_in == "quit":
        print("Goodbye")
        break
    
    try:
        card = _cardLibrary[u_in]
    except KeyError:
        print("Invalid choice. Please choose again")
        continue
    
    print(f"You played the {card['name']} card")
    for action in card['actions']:
        print("ACTION: ", end="")
        action(caster="You", target="Enemy")

这将给出以下输出:

You have 3 cards: 
strike, defend, bash

What would you like to do? (or quit) strike
You played the Strike card
ACTION: You dealt 10 damage to Enemy
You have 3 cards: 
strike, defend, bash

What would you like to do? (or quit) bash
You played the Bash card
ACTION: You dealt 5 damage to Enemy
ACTION: You applied 5xstun to Enemy
You have 3 cards: 
strike, defend, bash

What would you like to do? (or quit) defend
You played the Defend card
ACTION: You blocked 5 damage from Enemy
You have 3 cards: 
strike, defend, bash

What would you like to do? (or quit) quit
Goodbye
06odsfpq

06odsfpq2#

你可以让所有的函数参数列表都以,**_结尾,这将允许它们接收它们没有处理的参数,这将允许你直接在_cardLibrary字典中添加固定值参数,并将其用作函数的参数,然后定义你的use()函数,将它自己的命名参数列表添加到字典的固定值中作为覆盖:

def deal_damage(caster,target,basedamage,**_):
    # ...

def use(card, **kwargs):
    for function in _cardLibrary[card]:
        function(**{**_cardLibrary[card],**kwargs})

用法:

use(1,caster="orc",target="human")

相关问题