Python: 在不重命名的情况下使用来自不同函数的变量

Python: Using Variable From Different Function Without Renaming

我正在努力从游戏中创建一场简短的战斗(为了好玩)。我有几个变量需要在整个序列中更改,例如 m_hp(怪物健康)。这是我的代码(如果格式不正确,请原谅我,这是我第一次使用这个网站):

def battle(p_lvl):
    print("A goblin engages you in battle!")
    p_hp = p_lvl * 25 + 25
    p_dmg = p_lvl * 7 + 5
    print("Player Stats (Level: " + str(p_lvl) + " Health: " + str(p_hp) + " ATK: " + str(p_dmg) + ")")
    m_lvl = p_lvl - 1
    m_hp = m_lvl * 20 + 15
    m_dmg = m_lvl * 6 + 3
    scr_dmg = m_hp / 4
    dus_eft = p_hp / 5
print("Goblin Stats (Level: " + str(m_lvl) + " Health: " + str(m_hp) + " ATK: " + str(m_dmg) + ")")
act()

def act():
    menu = 'Attack','Block','Use Item'
    print("What will you do?")
    print(menu)
    action = input()
    if action == ‘Attack':
        m_hp = m_hp - p_dmg
        print("You dealt " + str(p_dmg) + "damage to the goblin!")
        p_hp = p_hp - m_dmg
        print("The goblin struck back with " + str(m_dmg) + " damage!”)
        act()

我在 act() 启动后遇到问题。如果我为 input() 输入 "attack",我会得到这个错误:

UnboundLocalError: local variable 'm_hp' referenced before assignment

据我了解,这是因为我将 m_hp 置于 battle() 下,但 act() 无法访问它。我希望能够更改 m_hp 而无需在 act() 中写入它。我相信如果我这样做,那么 m_hp 将在每次 act() 启动时重置,并且 m_hp 无法删除。我在这里搜索过问题,但我看到的案例似乎不起作用。另外,我承认我是编码新手,所以我无法理解一些解决方案。

Tl;dr 我正在寻找一个简单的解决方案,了解如何使用来自不同函数的变量而不将它们放入函数中。

您看到该错误消息是因为 'm_hp' 变量在 'battle' 函数的范围内是局部的。它在函数内部创建,并在该函数退出后不复存在。

虽然战斗实际上并没有在任何地方被调用... 看起来你在定义它之前调用了 act() 函数。

如果该错误也已修复,代码不会 运行 还有许多其他原因。

您可能正在寻找的功能是某种全局变量,您可以在其中访问多个函数中的变量而无需传入它们。一般而言,强烈建议不要在任何可以合理避免的地方使用全局变量。

我已经对您的代码进行了一些重组,以便您有一些工作可以解决。我已经使用 类 尝试将相关的事物组合在一起。

现在有一个包含所有玩家统计数据的 'Player' 对象和一个包含所有怪物统计数据的 'Monster' 对象。

尝试 运行 修改下面的代码,然后进行增量更改,看看它是否会继续 运行。

class Player(object):

    def __init__(self, level):
        self.level = level
        self.stats_for_level()

    def stats_for_level(self):
        self.attack_damage = (self.level * 7) + 5
        self.hitpoints = (self.level * 25) + 25

    def take_damage(self, damage):
        self.hitpoints -= damage

    def print_stats(self):
        print("Player Stats (Level: " + str(self.level) +
              " Health: " + str(self.hitpoints) +
              " ATK: " + str(self.hitpoints) + ")")


class Monster(object):
    def __init__(self, level, name="Goblin"):
        self.level = level
        self.name = name
        self.stats_for_level()

    def stats_for_level(self):
        self.attack_damage = (self.level * 6) + 3
        self.hitpoints = (self.level * 20) + 15

    def take_damage(self, damage):
        self.hitpoints -= damage

    def print_stats(self):
        print(self.name + " Stats (Level: " + str(self.level) +
              " Health: " + str(self.hitpoints) +
              " ATK: " + str(self.hitpoints) + ")")


class Game(object):

    def __init__(self, starting_level=1):
        self.player = Player(starting_level)

        # create monster
        self.monster = Monster(level=self.player.level - 1, name='Goblin')

    def battle(self, player, monster):
        print("A {} engages you in battle!".format(monster.name))
        monster.take_damage(player.attack_damage)
        print("You dealt " + str(player.attack_damage) + " damage to the goblin!")
        self.player.take_damage(monster.attack_damage)
        print("The goblin struck back with " + str(monster.attack_damage) + " damage!")


    def act(self):
        # print stats
        self.player.print_stats()
        self.monster.print_stats()

        # show menu
        menu = 'Attack', 'Block', 'Use Item'
        print(menu)
        print("\nWhat will you do?: ")
        action = input()

        # take an action
        if action == 'Attack':
            self.battle(self.player, self.monster)



def main():
    game = Game(starting_level=3)
    while(True):
        game.act()

if __name__ == '__main__':
    main()