使用 exec 修改 class 中的全局变量

Use exec to modify global variables in a class

我最近一直在重构我的一些代码以使用 OOP,但我 运行 遇到了一个问题,我无法完全获得全局变量 exec() 或两者结合起来工作。相关代码如下:

# invObject class. Has all properties of an inventory object.
class invObject:
    def __init__(self, name, info, output, effect):
        self.name = name # Used in menus.
        self.info = info # Describes effect.
        self.output = output # Printed on use.
        self.effect = effect # Executed on use.

    def printInfo(self): # Function for name and description.
        return "{} - {}".format(self.name, self.info)

    def use(self): # Function to use items. It's that easy.
        global dodgeChance
        global maxHp
        global hp
        global atk
        exec(self.effect)
        print(self.output) # Prints output. Also very simple.
        print("{} {} {} {}".format(dodgeChance, maxHp, hp, atk)) # debugging
...

inventory[slot].use() # does not update values

基本运行下:inventory[slot].use()应该调用对象的use()函数。 use() 应该执行存储在 inventory[slot].effect.

中的代码

调试行的输出没有任何改变,即使在函数内部也是如此。我已经尝试过 return exec(self.effect) 但无济于事。 print(self.output) 确实有效。

编辑:这是一个最小的可重现示例,其中包括 运行 所需的一切,而不仅仅是最重要的事情。

# Assign base stats
dodgeChance = 0
maxHp = int(input("Input maximum HP. > "))
hp = int(input("Input current HP. > "))

# invObject class. Has all properties of an inventory object.
class invObject:
    def __init__(self, name, info, output, effect):
        self.name = name # Used in menus.
        self.info = info # Describes effect.
        self.output = output # Printed on use.
        self.effect = effect # Executed on use.

    def printInfo(self): # Function for name and description.
        return "{} - {}".format(self.name, self.info)

    def use(self): # Function to use items. It's that easy.
        global dodgeChance
        global maxHp
        global hp
        global atk
        exec(self.effect)
        print(self.output) # Prints output. Also very simple.
        print("{} {} {} {}".format(dodgeChance, maxHp, hp, atk)) # debugging

empty = invObject("None", "Vacant slot.", "There's nothing in that slot!", "")
apple = invObject("Apple", "Gives 20 health.", "Ate the apple. Gained 20 health.", "hp = hp + 20\nif hp > maxHp: hp = maxHp")
drink = invObject("Drink", "Some kind of energy drink. Raises dodge chance to 75%.", "Drank the drink. Dodge chance is now 75%!", "dodgeChance = 75")

# Assign base inventory
inventory = [apple, drink, empty]

slot = int(input("Input slot number to use. ")) - 1
inventory[slot].use() # does not update values

# Show final stats
print("New HP value: " + str(hp))
print("Dodge chance: " + str(dodgeChance) + "%")
print()
print("Inventory contents:")
print("Slot 1: " + str(inventory[0].name))
print("Slot 2: " + str(inventory[1].name))
print("Slot 3: " + str(inventory[2].name))

编辑 2:另一件事:如果我不使用 exec()(例如,将其更改为 hp += 20),则代码有效。

exec() 有可选参数供您提供全局和局部变量上下文。

但是你没有提供。